如何在web api过滤器中清理字符串参数的值?

时间:2017-09-16 11:12:46

标签: c# asp.net-web-api filter

我有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",           "消息":"收集被修改;枚举操作可能无法执行。

但是如果我的web api动作将一个参数作为具有字符串属性的dto对象,则代码(在else语句中)完全正常工作,并且在开始执行操作之前对字符串进行清理。

所以我的问题是,如果它是字符串参数,如何清理传递的参数?

1 个答案:

答案 0 :(得分: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);
            }
        }
    }
}