2017-09-16 5 views
3

私はweb apiアプリケーションを持っており、Web APIフィルタを使用してフロントエンドアプリケーションからのデータをサニタイズする必要があります。Web APIフィルタ内の文字列引数の値をどのようにサニタイズするのですか?

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

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); 
       } 
      } 
     } 

    } 
} 

このコードの問題は、私はこのエラーを得た1つの文字列として渡される引数をサニタイズしたいの内部コードif文です:

私は、次のフィルタを作成しました

私のweb apiアクションが、文字列プロパティを持つdtoオブジェクトとしてパラメータを取る場合、コード(else文の中にあります)は完全に動作しており、アクションの実行を開始する前に文字列が消されます。

文字列パラメータの場合に渡された引数をどのようにサニタイズするのですか?

+0

同じコレクションを列挙中に変更しようとしていますが、これは許可されていません。 '.ToList()'を呼び出すと、オリジナルを変更しながら別のコレクションを列挙します。つまり、 'foreach(actionContext.ActionArguments.ToList()内のvar actionArgument){...' – 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; **であるべきだと思います –

関連する問題