Привязка модели

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 29.10.2015

Привязка модели представляет получение данных из HTTP-запроса для создания объекта, передаваемого в качестве аргумента в метод контроллера. Для WebApi есть два способа привязки: привязка по параметрам и собственно привязка модели. С обоими способами привязки мы можем столкнуться уже в стандартном приложении WebApi.

Например, в приложении по умолчанию определен один маршрут, который принимает параметр id:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
	routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
 );

И в контроллере определен такой метод, обрабатывающий запросы get:

public string Get(int id)
{
	return "value";
}

При обращении по запросу api/values/4 приложение будет сопоставлять последний сегмент строки запроса с параметром id.

Теперь добавим в файл WebApiConfig.cs новый маршрут:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

		config.Routes.MapHttpRoute(
            name: "TwoParamRoute",
            routeTemplate: "api/{controller}/{action}/{num1}/{num2}"
        );

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
	}
}

Здесь добавлен новый маршрут, который принимает пять сегментов: слово "api", название контроллера, метода и два параметра.

Определим в стандартном контроллере ValuesController соотстветсвующий данному маршруту метод:

public int GetValue(int num1, int num2)
{
    return num1 + num2;
}

Если мы обратимся к методу по запросу /api/values/getvalue/2/3, то приложение свяжет два последние сегмента с параметрами num1 и num2 и в ответ отправит сумму этих чисел.

Привязка по параметрам используется, когда параметры методов представляют примитивные типы: int, string, char, bool, uint, byte, sbyte, short, ushort, long, ulong, float, double и decimal. Либо параметры должны представлять простые типы: TimeSpan, DateTime, Guid.

Значения для параметров берутся из сегментов маршрута, либо из строки запроса. Так, вместо выше использованного запроса мы могли бы обратиться к ресурсу с помощью следующей строки запроса: api/values/getvalue?num1=2&num2=3

Привязка модели и встроенные привязчики

Привязка модели используется для параметров, представляющих сложные типы данных. Если у нас есть метод, который получает в качестве параметра модель Book, то передача параметров через сегменты маршрута или строку запроса уже работать не будут. В этом случае нам надо будет оправить запрос POST со всеми данными, и тогда стандартные механизмы WebApi попробуют связать отправленные в теле запроса данные со свойствами модели Book:

public Book Post(Book b)
{
	return b;
}

Чтобы связать данные с моделью, применяется один из привязчиков моделей. В Web Api в пространстве имен System.Web.Http.ModelBinding.Binders определено пять привязчиков моделей, которые покрывают большинство случаев, где необходима привязка:

  • ArrayModelBinder: используется для привязки к массивам

  • CollectionModelBinder: устанавливает привязку для строго типизированных коллекций

  • DictionaryModelBinder: устанавливает привязку для строго типизированных объектов Dictionary

  • MutableObjectModelBinder: связывает объекты

  • TypeConverterModelBinder: связывает объекты, применяя преобразование типов

Каждый привязчик моделей с помощью поставщиков значений берет из запроса данные и по ним создает объект модели. Сам процесс привязки разбивается на два этапа:

  1. С помощью конструктора без параметров создается объект модели

  2. Присвоение свойствам модели значений, полученных от поставщиков значений

Атрибуты привязки

Пространство имен System.Web.Http предоставляет нам ряд атрибутов, с помощью которых мы можем настроить механизм привязки.

Атрибут FromUri

Атрибут FromUri позволяет связать параметры с данным из строки запроса. Так, в предыдущем примере нам надо было отправить запрос POST для передачи на сервер данных о книге. Теперь же используем запрос GET и атрибут FromUri:

public Book GetValue([FromUri]Book b)
{
    return b;
}

Определим в WebApiConfig.cs соответствующий маршрут:

config.Routes.MapHttpRoute(
    name: "BookRoute",
    routeTemplate: "api/{controller}/{action}/{id}/{name}/{price}"
);

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

Чтобы передать данные для параметра, мы можем отправить такой запрос: api/values/getvalue/4/чайка/200. В итоге браузер нам выдаст следующую информацию:

{
  "Id": 4,
  "Name": "чайка",
  "Price": 200
}

Использование данного атрибута позволяет посылать серверу более сложные данные. Например, изменим метод следующим образом:

public string GetValue([FromUri]Book b, [FromUri]Author a)
{
    return b.Name + " ("+a.AuthorName+")";
}

Теперь метод получает еще и автора, который может быть представлен следующей моделью:

public class Author
{
    public int AuthorId { get; set; }
    public string AuthorName { get; set; }
    public int Year { get; set; }
}

Изменим выше определенный маршрут:

config.Routes.MapHttpRoute(
    name: "BookRoute",
    routeTemplate: "api/{controller}/{action}/{id}/{name}/{price}/{authorid}/{authorname}/{year}"
);

Важно, чтобы имена свойств обеих моделей не совпадали. И теперь мы можем обратиться к методу по запросу: api/values/getvalue/4/чайка/200/5/чехов/1860

Атрибут FromBody

Для привязки параметров к значениям, переданным в теле POST-запроса, используется атрибут FromBody. Хотя в большинстве случае он является избыточным.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850