Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Привязчик DefaultModelBinder используется по умолчанию, если для данного типа не определен другой привязчик. Чтобы получить значения для параметров, привязчик просматривает следующие объекты строго по порядку:
Request.Form
. В данном случае привязчик получает значения, отправленные с помощью форм
RouteData.Values
. Здесь получает значения с помощью маршрутов приложения
Request.QueryString
. В данном случае привязчик извлекает значения из строки запроса
Request.Files
. В данном случае используются загруженные на сервер файлы
Если в одном из этих объектов будет обнаружен соответствующий элемент, то на нем поиск прекращается, а параметру передается найденное значение. Например, привязчик ищет значения для параметров следующего действия:
public ActionResult Edit(int id) { // ... }
Чтобы DefaultModelBinder мог связать значение с параметром, элемент данных запроса должен обязательно иметь то же имя, что и параметр. То
есть в данном случае они оба должны иметь имя id
.
Итак, привязчик DefaultModelBinder просматривает в поиске значения для параметра id следующие пути:
Request.Form["id"]
RouteData.Values["id"]
Request.QueryString["id"]
Request.Files["id"]
При привязке простых типов DefaultModelBinder преобразует строковое выражение параметра из данных запроса к типу параметра с помощью
класса System.ComponentModel.TypeDescriptor
. Если же значение нельзя преобразовать, то привязка оканчивается неудачей. Поэтому
есть смысл использовать параметры, допускающие значение null
, а в метод действия вкладывать соответствующую логику по проверке значения:
public ActionResult Edit(int? id) { // ... }
При получении значений для сложных типов, например, для той же модели Book, DefaultModelBinder
с помощью рефлексии
просматривает объект и находит все свойства объекта, которые могут использоваться при привязке. Например, DefaultModelBinder
видит,
что объект Book
имеет свойство Author
, то привязчик будет искать в запросе параметр "Author".
Если свойство представляет простой тип, то для него используется, как было указано выше преобразование с помощью класса
System.ComponentModel.TypeDescriptor
. Если же свойство представляет сложный тип - то опять повторяется рефлексия и весь цикл.
Иногда возникает возможность исключить некоторые свойства из привязки модели. Мы можем это сделать с помощью атрибута Bind
.
Для включения только определенных свойств мы можем использовать свойство Include
данного атрибута:
public ActionResult Create([Bind (Include="Name, Author")] Book b) { // ... }
В данном случае мы указываем, что в привязке будут участвовать только свойства Name
и Author
. Остальные же свойства
из привязки исключаются.
Либо мы можем использовать свойство Exclude
атрибута Bind, чтобы исключить свойство из привязки:
public ActionResult Create([Bind (Exclude="Year")] Book b) { // ... }
В данном случае выборочная привязки применена к методу Create. Что если нам надо осуществить выборочную привязку глобально во всем приложении? Тогда мы можем применить атрибут непосредственно к модели, и в этом случае атрибут будет применен по умолчанию ко всем методам действий контроллеров проекта
[Bind (Exclude="Year")] public class Book { [ScaffoldColumn(false)] public int Id { get; set; } [Required (ErrorMessage="Поле должно быть установлено")] [Display(Name = "Название")] public string Name { get; set; } [Required] [Display(Name = "Автор")] public string Author { get; set; } [Display(Name = "Год")] public int Year { get; set; } }