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). Однако, если я украшу параметр, это не повлияет на привязку модели.
Ответы
Ответ 1
По умолчанию связующее ищет данные в четырех местах: данные формы, данные маршрута, строку запроса и любые загруженные файлы.
Можно ограничить привязку к одному источнику данных. Для этого вы должны вызвать метод UpdateModel, как второй параметр, объект FormValueProvider (реализация IValueProvider).
public ActionResult Products()
{
IList<Products> products = new List<Products>();
UpdateModel(products, new FormValueProvider(ControllerContext));
return View(products);
}
Полный список объектов (все они получают ControllerContext в качестве параметра contructor):
- FormValueProvider: поиск данных в теле (Request.Form)
- RouteDataValueProvider: поиск данных на маршруте (RouteData.Value)
- QueryStringValueProvider: поиск данных в строке запроса (Request.QueryString)
- HttpFileCollectionValueProvider: поиск загруженных файлов (Request.Files)
Ответ 2
Другой способ: создать привязку настраиваемой модели, которая использует 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;
}
}
И ваш метод действия:
[HttpPost]
public ActionResult Person(Person person)
{
return View(person);
}
Даже если вы отправляете сообщение с запросом, свойство ShouldNotBind
будет отображаться как "null".
Ответ 3
Почему бы не использовать форму?
При отправке данных вашей почтовой формы