C# 用于更改发布值的ActionFilter无法影响模型

C# 用于更改发布值的ActionFilter无法影响模型,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我们正试图以“全局”的方式清理ASP.NET MVC web应用程序中发布的字符串条目。在我当前的尝试中,我编写了一个自定义操作过滤器,并用我的类FormPostSanitizer装饰了一个post操作。我们的想法是,我们将装饰所有应该消毒的post操作 该方法成功捕获并清理输入。但是,在模型保存到数据库之前,这些经过清理的值不会固定到模型中 下面是它如何装饰控制器的 [HttpPost] [ValidateAntiForgeryToken] [FormPostSanitizer] public

我们正试图以“全局”的方式清理ASP.NET MVC web应用程序中发布的字符串条目。在我当前的尝试中,我编写了一个自定义操作过滤器,并用我的类FormPostSanitizer装饰了一个post操作。我们的想法是,我们将装饰所有应该消毒的post操作

该方法成功捕获并清理输入。但是,在模型保存到数据库之前,这些经过清理的值不会固定到模型中

下面是它如何装饰控制器的

[HttpPost]
[ValidateAntiForgeryToken]
[FormPostSanitizer]
public ActionResult MyAction(MyViewModel model)
{
    // If ModelState.IsValid, save the model ...
}
这是我的动作过滤器

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.HttpContext.Request.HttpMethod != "POST") return;

    FormCollection formCollection = new FormCollection(filterContext.Controller.ControllerContext.HttpContext.Request.Form);
    foreach (string key in formCollection.AllKeys)
    {
        string sanitized = formCollection[key].SanitizeString(); // Extension method to alter the string.
        formCollection.Set(key, sanitized);
    }
    filterContext.ActionParameters["form"] = formCollection;
}
我的期望是最后一行将更改的值提交到filterContext,并且模型将具有经过清理的值。这些值已被清理,但不会应用于模型


如果在编译后的代码中有更好的方法在将发布的值绑定到模型之前拦截和更改这些值,那么请给我指一篇展示方法的文章。谢谢您的帮助。

您可以为此创建自定义模型活页夹

public class SanitizeModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        bool sanitize = controllerContext.HttpContext.Request.HttpMethod == "POST";

        //get value from default binder
        object value = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
        if (!sanitize)
        {
            return value;
        }

        //sanitize value if it is a string
        string stringValue = value as string;
        if (stringValue != null)
        {
            return stringValue.SanitizeString();
        }

        return value;
    }
}
Global.asax.cs
中设置默认活页夹,以便在每次操作中使用它

System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new SanitizeModelBinder();
或者,如果您想对某些型号使用此活页夹

public ActionResult MyAction([ModelBinder(typeof(SanitizeModelBinder))]MyViewModel model)

您可以为此目的创建自定义模型绑定器

public class SanitizeModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        bool sanitize = controllerContext.HttpContext.Request.HttpMethod == "POST";

        //get value from default binder
        object value = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
        if (!sanitize)
        {
            return value;
        }

        //sanitize value if it is a string
        string stringValue = value as string;
        if (stringValue != null)
        {
            return stringValue.SanitizeString();
        }

        return value;
    }
}
Global.asax.cs
中设置默认活页夹,以便在每次操作中使用它

System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new SanitizeModelBinder();
或者,如果您想对某些型号使用此活页夹

public ActionResult MyAction([ModelBinder(typeof(SanitizeModelBinder))]MyViewModel model)

您必须使用自定义模型绑定器,如上面解释的Alexandar,因为动作过滤器属性是在模型已经绑定之后执行的,此时您无法更改它。
如果您在模型绑定器中执行此操作,那么它将按照您的预期应用于模型

您必须使用自定义模型绑定器,如上文所述的Alexandar,因为动作过滤器属性是在模型绑定后执行的,此时您无法更改它。
如果您在模型活页夹中这样做,那么它将按照您的预期应用于模型

这不是您要找的吗这不是您要找的吗谢谢Alexander。我带着这个跑,谢谢你,亚历山大。我带着这个跑。