Asp.Net MVC 5仅从body绑定参数

Den*_*s K 11 asp.net asp.net-mvc model-binding asp.net-mvc-5

我想防止通过url查询字符串将敏感数据发布到MVC 5应用程序.

在MVC中有一个DefaultModelBinder.的DefaultModelBinder外观为ActionMethod在URL查询字符串,身体和路由参数.但我的目标是仅从主体绑定参数,而不是路由或查询字符串.

在Asp.Net WebApi中有这样一个概念.属性[FromBody]将完成这项工作:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

有适合MVC的东西吗?

我找到了System.Web.ModelBinding.FormAttribute(https://msdn.microsoft.com/en-us/library/system.web.modelbinding.formattribute(v=vs.110).aspx).但是,如果我装饰参数,它对模型绑定没有影响.

Raf*_*oni 6

默认情况下,binder在四个位置查找数据:表单数据,路由数据,查询字符串和任何上载的文件.

可以将绑定限制为单个数据源.为此,您应该调用UpdateModel方法,作为第二个参数传递FormValueProvider对象(IValueProvider的实现).

public ActionResult Products()
{
    IList<Products> products = new List<Products>();
    UpdateModel(products, new FormValueProvider(ControllerContext));
    return View(products);
}
Run Code Online (Sandbox Code Playgroud)

完整的对象列表是(它们都接收ControllerContext作为contructor参数):

  • FormValueProvider:搜索正文中的数据(Request.Form)
  • RouteDataValueProvider:搜索路径中的数据(RouteData.Value)
  • QueryStringValueProvider:在查询字符串中搜索数据(Request.QueryString)
  • HttpFileCollectionValueProvider:搜索上传的文件(Request.Files)


Mar*_*ari 5

另一种方法:创建一个使用FormValueProvider自定义模型绑定.这样做的好处是您不必修改操作方法.

例:

[ModelBinder(typeof(PersonBinder))]
public class Person
{
    [DisplayName("Social Security Number")]
    public int SSN { get; set; }

    [HiddenInput(DisplayValue = false)]
    public string ShouldNotBind { get; set; }
}

public class PersonBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        bindingContext.ValueProvider = new FormValueProvider(controllerContext);
        Person model = (Person)bindingContext.Model ?? new Person();
        model.SSN = Convert.ToInt16(GetValue(bindingContext, "SSN"));
        return model;
    }

    private string GetValue(ModelBindingContext context, string name)
    {
        ValueProviderResult result = context.ValueProvider.GetValue(name);
        if (result == null || result.AttemptedValue == "")
        {
            return "<Not Specified>";
        }
        return result.AttemptedValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

你的行动方法:

[HttpPost]
public ActionResult Person(Person person)
{
    return View(person);
}
Run Code Online (Sandbox Code Playgroud)

即使您使用查询字符串发布,该ShouldNotBind属性也将显示为"null".