Связывание моделей

Rachel Appel

Введение в связывание моделей

Связывание моделей в ASP.NET Core MVC переводит данные из HTTP запросов в параметры методов действий. Параметры могут быть простыми типами, например, строками, или же они могут быть сложными типами. Это отличная возможность в MVC, поскольку передача данных методам действий - это зачастую повторяющийся сценарий, независимо от размера и сложности данных. MVC решает эту проблему, абстрагируя связывание, так что разработчикам не нужно переписывать фактически одинаковый код для каждого приложения.

Как работает связывание моделей

Когда MVC получает HTTP запрос, он направляет его к конкретному методу действия контроллера. Он определяет, какой метод действия должен быть запущен, основываясь на роутовых данных, а затем он связывает значения HTTP запроса с параметрами метода действия. Например, у нас есть вот такой URL:

http://contoso.com/movies/edit/2

Поскольку роутовый шаблон выглядит вот так: {controller=Home}/{action=Index}/{id?}, movies/edit/2 перенаправляется к контроллеру Movies и его методу действия Edit. Он также принимает дополнительный параметр id. Метод действия должен выглядеть примерно вот так:

1
public IActionResult Edit(int? id)

Примечание

Строки в URL роуте не чувствительны к регистру.

MVC попытается связать данные запроса с параметрами метода действия по имени. MVC будет искать значения для каждого параметра, используя имя параметра и его открытых свойств. В примере выше только один параметр называется id, и MVC связывает его со значением роута с таким же именем. Далее представлен список источников, по которым идет связывание моделей:

  1. Значения формы: они передаются HTTP запросу с помощью метода POST (включая запросы jQuery POST).
  2. Роутовые значения: передаются через роутинг.
  3. Строки запросов: часть URI.

Примечание

Значения формы, роутовые значения и строки запросов хранятся как пары имя-значение.

Поскольку механизм связывания моделей искал ключ с именем id, а в значениях формы нет ничего с таким именем, он переходит к роутовым значениям и ищет ключ. В нашем примере есть совпадение. Происходит связывание и значение конвертируется в 2.

В примере мы используем простые типы. В MVC простыми типами являются все простые типы .NET или типы, конвертируемые в строку. Если параметрами метода действия являются и простые, и сложные типы, MVC все равно их обработает. Он использует рефлексию и рекурсию. Механизм связывания моделей ищет паттерн parameter_name.property_name, чтобы связать значения со свойствами. Если он не находит подходящих значений формы, он попытается произвести связывание, используя только имя свойства. Для таких типов как Collection механизм связывания ищет совпадения с parameter_name[index] или просто [index]. Схожим образом он обрабатывает и типы Dictionary, запрашивая parameter_name[key] или просто [key]. Поддерживаемые ключи совпадают с именами полей HTML и тег-хелперами, сгенерированными для одно типа модели.

Чтобы произошло связывание, у класса должен быть открытый конструктор, а элемент связывания должен быть открытым свойством. Когда происходит связывание моделей, создается экземпляр класса с помощью открытого конструктора по умолчанию, а затем можно установить свойства.

После связывания параметра механизм прекращает искать совпадения с этим именем и переходит к следующему параметру. Если связывание не происходит, MVC не выбрасывает ошибку. Вы можете отслеживать ошибки состояния модели, используя свойство ModelState.IsValid.

Примечание

В ModelStateEntry содержится Errors property. В принципе, нам нет необходимости запрашивать эту коллекцию. Вместо это мы используем ModelState.IsValid.

Есть некоторые специальные типы, которые учитываются при связывании данных:

  • IFormFile, IEnumerable<IFormFile>: один или несколько закачанных файлов, которые являются частью HTTP запроса.
  • CancelationToken: используется для отмены работы в асинхронных контроллерах.

Эти типы можно связать с параметрами действия или свойствами класса.

После связывания моделей происходит валидация. Связывание моделей отлично подходит для большинства сценариев разработки.

Настройка связывания моделей с помощью атрибутов

MVC содержит несколько атрибутов, которые можно использовать для настройки связывания моделей. Например, вы можете указать, должно ли произойти связывание или нет, используя атрибуты [BindRequired] или [BindNever]. Ниже представлен список атрибутов для связывания моделей:

  • [BindRequired]: Этот атрибут добавляет ошибку связывания моделей, если связывание не может произойти.
  • [BindNever]: Говорит механизму никогда не связываться с этим параметром.
  • [FromHeader], [FromQuery], [FromRoute], [FromForm]: Используется для указания точного источника для связывания.
  • [FromServices]: Этот атрибут использует внедрение зависимостей, чтобы связывать параметры из сервисов.
  • [FromBody]: Использует настроенные форматтеры для связывания данных из тела запроса. Форматтер выбирается на основании типа контента запроса.
  • [ModelBinder]: Используется для переопределения механизма связывания моделей по умолчанию, источника связывания и имени.

Атрибуты очень полезны, если вам необходимо переопределить поведение по умолчанию для механизма связывания моделей.

Связывание форматированных данных из тела запроса

Данные запроса могут быть в разных форматах, включая JSON, XML и так далее. Если вы используете атрибут [FromBody], MVC пользуется настроенным набором форматтеров для обработки данных, основываясь на типе контента. По умолчанию MVC включает в себя класс JsonInputFormatter для обработки JSON данных, но вы можете включить дополнительные форматтеры для работы с XML и других форматов.

Примечание

Только одному параметру в методе действия можно добавить [FromBody]. ASP.NET Core MVC передает ответственность за прочтение потока запроса форматтеру. После прочтения потока он не может снова прочесть поток для связывания других параметров [FromBody].

Примечание

JsonInputFormatter является форматтером по умолчанию и основывается на Json.NET.

ASP.NET выбирает форматтеры ввода, основываясь на заголовке Content-Type и типе параметра, если здесь нет атрибута, переопределяющего поведение. Если вы хотите использовать XML или другой формат, вы должны настроить это в файле Startup.cs, но сперва вам нужно получить ссылку на Microsoft.AspNetCore.Mvc.Formatters.Xml с помощью NuGet. Код для запуска должен выглядеть примерно так:

1
2
3
4
5
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
       .AddXmlSerializerFormatters();
}

Код в файле Startup.cs содержит метод ConfigureServices с аргументом services , который вы можете использовать для создания сервисов для вашего ASP.NET приложения. В нашем примере мы добавляем XML форматтер в качестве сервиса. Аргумент options, переданный методу AddMvc, позволяет вам добавлять и управлять фильтрами, форматтерами и другими опциями. Затем нужно просто добавить Consumes в контроллер или метод действия, чтобы работать с желаемыми форматами.

Поделись хорошей новостью с друзьями!
Следи за новостями!