我有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语句中)完全正常工作,并且在开始执行操作之前对字符串进行清理。
所以我的问题是,如果它是字符串参数,如何清理传递的参数?
答案 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);
}
}
}
}