ModelState действителен с нулевой моделью
У меня есть объект Model с обязательным атрибутом
public class ApiPing
{
[Required]
public DateTime ClientTime { get; set; }
public DateTime ServerTime { get; set; }
}
У меня есть метод Controller, который проверяет состояние модели.
public IHttpActionResult Ping(ApiPing model)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
model.ServerTime = DateTime.UtcNow;
return Ok(model);
}
Если я отправлю соответствующий запрос (с моделью) в метод действия, я получаю правильное значение из ModeState.IsValid(true). Однако, когда я отправляю неверный запрос (без модели, поэтому модель равна нулю), я получаю ошибочный ModelState.IsValid(также верно).
Я мог бы просто проверить, является ли модель нулевым в моем коде, но это пахнет. Является ли это предполагаемой "особенностью" или ошибкой в проверке ModelState? Я делаю что-то неправильно? Я ожидаю слишком много?
Ответы
Ответ 1
У меня была такая же проблема раньше, и ответ уже доступен на нескольких форумах и даже здесь в SO: ModelState.IsValid, даже если это не должно быть?
Вы также можете добавить настраиваемый фильтр для проверки (недействительности) отсутствующих полей и/или нулевых значений
http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api
http://www.strathweb.com/2012/10/clean-up-your-web-api-controllers-with-model-validation-and-null-check-filters/
Ответ 2
Вот фильтр действий для проверки нулевых моделей или недопустимых моделей.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Studio.Lms.TrackingServices.Filters
{
public class ValidateViewModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ActionArguments.Any(kv => kv.Value == null)) {
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Arguments cannot be null");
}
if (actionContext.ModelState.IsValid == false) {
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
}
Вы можете зарегистрировать его по всему миру:
config.Filters.Add(new ValidateViewModelAttribute());
Или использовать его по требованию по классам/действиям
[ValidateViewModel]
public class UsersController : ApiController
{ ...
Ответ 3
- Объявить вашу модель как структуру
- Измените тип всех необходимых свойств, которые должны быть нулевыми.