Asp.Net MVC 5 bind parameter exclusively from body

后端 未结 3 1495
忘掉有多难
忘掉有多难 2020-12-16 01:40

I want to prevent posting sensitive data via url query string to a MVC 5 application.

In MVC there is a DefaultModelBinder. The DefaultModelBinder

相关标签:
3条回答
  • 2020-12-16 01:46

    Another way: create a custom model binder that uses FormValueProvider. The advantage of this is that you don't have to modify the action method.

    Example:

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

    And your action method:

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

    Even if you post with a querystring, the ShouldNotBind property will show as "null".

    0 讨论(0)
  • 2020-12-16 02:00

    Why not use form's then? On submit you post form data

    0 讨论(0)
  • 2020-12-16 02:11

    By default, the binder looks for data in four places: form data, route data, the query string, and any uploaded files.

    It is possible to restrict the binding to a single source of data. To do so you should call the UpdateModel method passing, as the second parameter, a FormValueProvider object( an implementation of IValueProvider).

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

    The complete list of objects is (they all receive the ControllerContext as the contructor parameter):

    • FormValueProvider: search for data in the body (Request.Form)
    • RouteDataValueProvider: search for data in the route (RouteData.Value)
    • QueryStringValueProvider: search for data in the query string (Request.QueryString)
    • HttpFileCollectionValueProvider: search for uploaded files (Request.Files)
    0 讨论(0)
提交回复
热议问题