Что такое привязка модели (model binding) параметров в ASP.NET Core?

«Что такое привязка модели (model binding) параметров в ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Привязка модели (Model Binding) в ASP.NET Core — это процесс, в ходе которого фреймворк автоматически извлекает данные из HTTP-запроса (из строки запроса, тела, заголовков, маршрута) и преобразует их в параметры методов контроллера или Razor Page. Это избавляет разработчика от ручного парсинга сырых данных запроса.

Источники данных для привязки (в порядке приоритета по умолчанию):

  1. Из значений маршрута: {id} в шаблоне [Route("api/products/{id}")].
  2. Из строки запроса (Query String): ?page=1&sort=name.
  3. Из тела запроса (Body): Данные в формате JSON, XML, form-data.
  4. Из заголовков (Headers).
  5. Из предоставленной формы (Form fields).

Как это работает:

  1. При поступлении запроса ASP.NET Core ищет метод действия (Action) в контроллере.
  2. Для каждого параметра метода система привязки ищет совпадение по имени (или с помощью атрибутов) в источниках данных запроса.
  3. Найденные строковые значения преобразуются (парсятся) в типы параметров (int, DateTime, сложные объекты).

Практические примеры:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // Пример 1: Привязка из нескольких источников
    // GET api/products/5?details=true
    [HttpGet("{id}")]
    public IActionResult GetProduct(int id, // Из маршрута {id}
                                    bool details) // Из query string ?details=true
    {
        // ...
    }

    // Пример 2: Привязка сложного объекта из тела запроса (JSON)
    // POST api/products
    [HttpPost]
    public IActionResult CreateProduct(Product product) // Данные автоматически десериализуются из Body
    {
        // Свойства объекта Product (Name, Price) заполнены из JSON-тела запроса
        // ...
    }

    // Пример 3: Явное указание источника с помощью атрибутов
    [HttpGet("search")]
    public IActionResult Search([FromQuery] string term, // Только из строки запроса
                                [FromHeader("X-API-Key")] string apiKey) // Только из заголовка
    {
        // ...
    }
}

public class Product
{
    public int Id { get; set; } // Может привязываться из маршрута или тела
    public string Name { get; set; } // Обычно из тела запроса
    public decimal Price { get; set; }
}

Важные аспекты:

  • [ApiController] атрибут автоматически делает вывод о том, что сложные типы привязываются из тела запроса, а простые — из строки запроса.
  • Валидация модели: После успешной привязки можно проверить данные с помощью атрибутов валидации ([Required], [Range]), вызвав ModelState.IsValid.
  • Кастомизация: Поведение привязки можно настраивать через поставщиков значений (IValueProvider) и связывателей моделей (IModelBinder).