2017-09-16 25 views
3

我有web api應用程序,我想使用web api過濾器清理來自前端應用程序的數據。如何清理web api過濾器中字符串參數的值?

我創建了以下過濾器:

public class StringFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     foreach (var actionArgument in actionContext.ActionArguments) 
     { 
      if (actionArgument.Value.GetType() == typeof(string)) 
      { 
       var sanitizedString = actionArgument.Value.ToString().Trim(); 
       sanitizedString = Regex.Replace(sanitizedString, @"\s+", " "); 
       actionContext.ActionArguments[actionArgument.Key] = sanitizedString; 
      } 
      else 
      { 
       var properties = actionArgument.Value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) 
        .Where(x => x.CanRead && x.PropertyType == typeof(string) && x.GetGetMethod(true).IsPublic && x.GetSetMethod(true).IsPublic); 
       foreach (var propertyInfo in properties) 
       { 
        var sanitizedString = propertyInfo.GetValue(actionArgument.Value).ToString().Trim(); 
        sanitizedString = Regex.Replace(sanitizedString, @"\s+", " "); 
        propertyInfo.SetValue(actionArgument.Value, sanitizedString); 
       } 
      } 
     } 

    } 
} 

這段代碼的問題是裏面的代碼if語句,我想消毒作爲單個字符串傳遞的參數,我得到這個錯誤:

"ClassName": "System.InvalidOperationException", "Message": "Collection was modified; enumeration operation may not execute.

但是,如果我的web api動作將一個參數作爲具有字符串屬性的dto對象,則代碼(它位於else語句中)完美工作,字符串在開始執行動作之前已經過清理。

所以我的問題如何清理傳遞的參數,以防萬一它是字符串參數?

+0

您正在嘗試修改相同的集合,同時枚舉它,這是不允許的。調用'.ToList()',以便在修改原始數據時枚舉單獨的集合。即'foreach(var actionArgument in actionContext.ActionArguments.ToList()){...' – Nkosi

+0

@Nkosi你是對的。非常感謝你,現在它工作。 –

回答

1

您正在嘗試在枚舉它的同時修改相同的集合,這是不允許的。請致電.ToList(),以便在修改原稿時枚舉單獨的集合。即foreach (var actionArgument in actionContext.ActionArguments.ToList()) {...

public override void OnActionExecuting(HttpActionContext actionContext) { 
    foreach (var actionArgument in actionContext.ActionArguments.ToList()) { 
     if (actionArgument.Value != null && actionArgument.Value is string) { 
      var sanitizedString = actionArgument.Value.ToString().Trim(); 
      sanitizedString = Regex.Replace(sanitizedString, @"\s+", " "); 
      actionContext.ActionArguments[actionArgument.Key] = sanitizedString; 
     } else { 
      var properties = actionArgument.Value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) 
       .Where(x => x.CanRead && x.PropertyType == typeof(string) && x.GetGetMethod(true).IsPublic && x.GetSetMethod(true).IsPublic); 
      foreach (var propertyInfo in properties) { 
       var sanitizedString = propertyInfo.GetValue(actionArgument.Value).ToString().Trim(); 
       sanitizedString = Regex.Replace(sanitizedString, @"\s+", " "); 
       propertyInfo.SetValue(actionArgument.Value, sanitizedString); 
      } 
     } 
    } 
} 
+0

但我認爲這應該是** actionContext.ActionArguments [actionArgument.Key] = sanitizedString; ** –