【问题标题】:Asp.Net MVC 5 bind parameter exclusively from bodyAsp.Net MVC 5 绑定参数完全来自正文
【发布时间】:2015-11-07 20:11:17
【问题描述】:

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

在 MVC 中有一个 DefaultModelBinderDefaultModelBinder 在 url 查询字符串、正文和路由中查找 ActionMethod 参数。但我的目标是只从正文中绑定参数,而 not 从路由或查询字符串中绑定。

在 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)。但是,如果我装饰参数,它对模型绑定没有影响。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-5 model-binding


    【解决方案1】:

    那为什么不使用表单呢? 在提交时您发布表单数据

    【讨论】:

    • 不知道你的意思。 Asp.Net Web Forms 不是替代品。
    • 添加 -> 查看。选择模板“编辑”。选择你的模型类。它将为您自动生成表格。到时候你就明白了
    • 好的,我知道了。当然,这是我渲染表单的方式。每个“普通”用户都会在正文上发布数据。但是任何人都可以在查询字符串中发送带有参数的请求,MVC 将绑定它们。这就是我想防止的情况。
    • 将表单设为 POST。然后在方法上添加属性 [HttpPost]。现在将无法使用 url
    • 不,我认为这是不正确的。使用 [AcceptVerbs(HttpVerbs.Post)] 装饰 ActionMethod 会强制 MVC 仅接受 HttpPost。但是您仍然可以在查询字符串中传递您的数据。
    【解决方案2】:

    默认情况下,活页夹在四个位置查找数据:表单数据、路由数据、查询字符串和任何上传的文件。

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

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

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

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

    【讨论】:

    • 谢谢,这就是我要找的。我希望它可以通过属性来完成。但这也是一个很好的解决方案。顺便说一句,我将使用TryUpdateModel()
    【解决方案3】:

    另一种方法:创建一个使用 FormValueProvider自定义模型绑定器。这样做的好处是不用修改action方法。

    例子:

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

    还有你的操作方法:

    [HttpPost]
    public ActionResult Person(Person person)
    {
        return View(person);
    }
    

    即使您使用查询字符串发布,ShouldNotBind 属性也会显示为“null”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 2010-10-13
      • 2014-02-02
      • 1970-01-01
      相关资源
      最近更新 更多