Jeer
@Jeer
уверенный пользователь

Почему валидация DataAnnotation отрабатывает до тела контроллера и возвращает сразу результат?

Привет всем любителям си решётка.
Использую .net core версии 3.0, пустой mvc проект
Пишу метод в контроллере на создание какой-то сущности:
[HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> Create([FromBody] TimeTrackingDto timeTrackingDto)
        {
            timeTrackingDto.UserId = HttpContext.User.GetUserId();

            if (ModelState.IsValid)
            {
                var id = await service.Create(timeTrackingDto);
                return Ok(id);
            }
            else
            {
                return BadRequest(ModelState);
            }
        }

В моделе есть поле UserId помеченное атрибутом, например,
[Required]
  public Guid UserId { get; set; }

Я планировал в методе Create заполнить это поле текущим пользователем (до передачи управления в сервис, который пишет в базу), а в методе Update поле и так должно быть заполнено, поэтому хочу оставить одну модель и для создания и для обновления сущности.

Суть вопроса в чём. В метод Create управление не заходит. То есть, если я там поставлю точку останова на первой строчке и запущу в режиме дебаггера, я никогда не попаду в этот метод. Всегда возвращается 400 ошибка с телом ModelState и ошибками. Даже если я напишу вот такой метод:
[HttpPost]
  [Route("[action]")]
  public async Task<IActionResult> Create([FromBody] TimeTrackingDto timeTrackingDto)
  {
    return Ok();
  }

Ответом всё равно будет 400 с телом ModelState.
Если же я уберу все DataAnnotation атрибуты, то управление спокойно зайдёт в метод.

Насколько я понимаю, это неправильное поведение. Даже если на сервер пришла некорректная (не валидная) модель, я хочу вручную установить некоторые поля и дальше вручную проверить ModelState.IsValid. Мне казалось, что ранее (я давно за этим не следил, в .net framework и даже в .net core ранних версий) было именно такое поведение.

В стартапе нет никаких переопределений такого поведения.
Всё что я гуглю ведёт на примитивные статьи как эта валидация работает и ни слова о таком поведении и как с этим быть.
Разумеется костылями я могу сделать корректное поведение, это не предлагать.
Хочу разобраться в данном вопросе, подскажите, пожалуйста.
  • Вопрос задан
  • 68 просмотров
Решения вопроса 1
yarosroman
@yarosroman Куратор тега C#
C# the best
Судя по коду у вас Api контроллер.

Контроллерам веб-API не нужно проверять ModelState.IsValid при наличии атрибута [ApiController]. В этом случае автоматически возвращается ответ HTTP 400, содержащий сведения об ошибке, если состояние модели недопустимо. Дополнительные сведения см. в разделе Автоматические отклики HTTP 400.

https://docs.microsoft.com/ru-ru/aspnet/core/mvc/m...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы