MVC 5, Прив’язка моделі
- це процес створення об'єктів .NET з використанням даних, надісланих браузером у HTTP-запиті. Ми покладаємося на процес прив'язки моделей щоразу, коли визначаємо метод дії, який приймає параметр. Об'єкти параметрів створюються за допомогою прив'язки моделей даних у запиті. Далі буде показано, як працює система прив'язки моделей, та продемонстровані способи її налаштування для розширеного використання.
Приклад проекту
Для цілей цієї та наступних статей у Visual Studio створено новий проект MVC на ім'я MvcModels з використанням шаблону Empty (Порожній) та позначкою прапорця MVC у розділі Add folders and core references for (Додати папки та основні посилання для).
Також визначено контролер Home, код якого показано на прикладі нижче. У цьому контролері визначено колекцію об'єктів User та дію Index, що дозволяє вибирати одиночний об'єкт User за значенням властивості UserId:
Для підтримки методу дії Index() створено файл подання /Views/Index.cshtml, вміст якого наведено у прикладі нижче. У ньому за допомогою шаблонізованого допоміжного методу відображаються значення деяких властивостей моделі User:
Нарешті, створюється папка Views/Shared, до якої додається компонування на ім'я _Layout.cshtml:
Поняття прив'язки моделей
Прив'язка моделей є елегантним містом між HTTP-запитом і методами C#, що визначають дії. Більшість програм ASP.NET MVC Framework в тій чи іншій мірі покладаються на прив'язку моделей, у тому числі простий приклад програми, створений у попередньому розділі. Щоб побачити прив'язку моделей у роботі, запустіть програму та перейдіть на /Home/Index/1. Результат показаний нижче.

Вказаний URL містить значення властивості UserId об'єкта User, який необхідно відобразити, наприклад:
Інфраструктура ASP.NET MVC Framework транслює цю частину URL і застосовує її як аргумент при викликі методу Index() класу контролера Home з метою обслуговування запиту:
Процес, за допомогою якого сегмент URL був перетворений в аргумент методу int, є прикладом прив'язки моделей. У наступних розділах буде описаний процес, який ініціюється цією простою демонстрацією, і потім пояснено складніші функціональні можливості прив'язки моделей.
Процес, що призводить до прив'язки моделей, починається відразу після отримання запиту та його обробки механізмом маршрутизації. У цьому прикладі програми конфігурація маршрутизації не змінювалася, тому для обробки запиту використовувався стандартний маршрут, який середовище Visual Studio додає файл /App_Start/RouteConfig.cs. Як нагадування, цей стандартний маршрут наведено нижче:
Питання визначення та роботи маршрутів докладно розглядалися раніше, тому тут вони не повторюватимуться. Для процесу прив'язки моделей важливою частиною є необов'язкова змінна сегмента id. При переході на URL виду /Home/Index/1 останній сегмент, який вказує об'єкт User, що цікавить, присвоюється змінній маршрутизації id.
Активатор дій використовує інформацію про маршрутизацію для з'ясування того, що для обслуговування запиту потрібен метод дії Index(), але не може викликати метод Index() доти, доки не матиме відповідні значення аргументу цього методу.
Стандартний активатор дій, ControllerActionInvoker, покладається на зв'язувачі моделей при генерації об'єктів даних, які потрібні для виклику методу. Зв'язувачі моделей визначаються зза допомогою інтерфейсу IModelBinder, який показано на прикладі нижче. Ми ще повернемося до цього інтерфейсу пізніше, коли розглядатиметься створення спеціального зв'язувача моделі.
У програмі MVC може бути безліч зв'язувачів моделей, кожен з яких відповідає за прив'язку одного або більше типів моделей. Коли активатор дій повинен викликати метод дії, він переглядає параметри, що визначаються методом, і для кожного типу параметра шукає зв'язувач моделі, що відповідає за це.
У прикладі вище, наведеному в цьому розділі, активатор дій перевірятиме метод Index() і виявить, що він приймає один параметр int. Потім активатор дій знайде зв'язувач, відповідальний значення int, і викличе його метод BindModel().
Зв'язувач моделі відповідає за надання значення int, яке можна використовувати для виклику методу Index(). Це зазвичай означає трансформацію деякого елемента даних запиту (такого як значення форми або рядка запиту), але інфраструктура ASP.NET MVC Framework не обмежує спосіб отримання даних.
Пізніше буде надано приклади спеціальних зв'язувачів. Крім того, буде продемонстровано певні можливості класу ModelBindingContext, екземпляр якого передається методу IModelBinder.BindModel().
Використання стандартного зв'язувача моделі
Незважаючи на те, що в додатку можуть бути визначені спеціальні зв'язувачі моделей, найпростіше покластися на вбудований клас зв'язувача - DefaultModelBinder. Цей зв'язувач використовується активатором дій, коли той не може знайти спеціальний зв'язувач для прив'язки конкретного типу. За замовчуванням цей зв'язувач моделі здійснює пошук даних, відповідних імені параметра, що прив'язується, в чотирьохрозташування, які описані нижче:
Request.Form
Значення, надані користувачем HTML-елементах .
Коли форма відправляється, стандартний зв'язувач моделі з'ясовує, що метод дії вимагає рядковий масив, і здійснює пошук елементів даних, що мають те саме ім'я в якості параметра. У цьому прикладі разом збирається вміст всіх елементів для заповнення масиву. Результат роботи методу дії та подання можна бачити на малюнку нижче:

Прив'язка колекцій
Прив'язку можна здійснювати не тільки для масивів, але також для класів колекцій .NET. У наведеному нижче прикладі показано, як змінити тип параметра методу дії Names(), щоб він став строго типізованим списком:
Нижче наведено модифікований вміст файлу представлення Names.cshtml, в якому застосовується новий тип моделі:
Функціональність дії Names не змінилася, але тепер можна працювати з колекцією, а чи не масивом.
Прив'язка колекцій спеціальних типів моделей
Індивідуальні властивості даних можна прив'язувати до масиву спеціальних типів, такому як клас моделі AddressSummary. У прикладі нижче видно, що ми додали новий метод дії на ім'я Address, який приймає як параметр строго типізовану колекцію, яка покладається на спеціальний клас моделі:
Для цього методу дії створено файл подання /Views/Home/Address.cshtml, вміст якого показаний у прикладі нижче:
Це представлення візуалізує елемент , якщо елементи колекції моделі відсутні. Елемент складається з пари елементів, атрибути name яких мають префікси у вигляді індексу масиву в результуючій HTML-розмітці:
Коли форма відправляється, стандартний зв'язувачМодель визначає, що необхідно створити колекцію об'єктів AddressSummary, і використовує префікси індексів масиву в атрибутах name для отримання значень, призначених для властивостей цих об'єктів. Властивості з префіксом [0] використовуються для першого об'єкта AddressSumary, властивості з префіксом [1] - для другого об'єкта AddressSumary і т.д.
Подання Address.cshtml визначає елементи для трьох таких індексованих об'єктів і відображає їх у ситуації, коли колекція моделі містить елементи. Перед тим, як це можна буде продемонструвати в роботі, необхідно видалити атрибут Bind із класу моделі AddressSummary, як показано в прикладі нижче, інакше зв'язувач моделі проігнорує властивість Country: