Контроллер API передал недопустимый JSON, получает null

Я использую класс ApiController ASP.NET для создания веб-API. Я обнаружил, что если я передам недопустимый JSON, вместо того, чтобы вызывающий абонент получил 500, входной параметр будет нулевым. Как в случае, если я пройду

{ "InputProperty:" "Some Value" }

что явно недопустимо для этого метода:

[HttpPost]
public Dto.OperationOutput Operation(Dto.OperationInput p_input)
{
    return this.BusinessLogic.Operation(p_input);
}

Я понимаю, что p_input это null. Я бы предпочел отправить что-нибудь обратно, сообщив пользователю, что они не отправили действительный JSON на POST.

В моем WebApiConfig.cs есть:

config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
config.Formatters.XmlFormatter.UseXmlSerializer = true;

Любые идеи? Я видел этот пример, но я считаю, что это ASP.NET MVC, а не ApiController.


person Don 01001100    schedule 26.11.2013    source источник
comment
@greetings: meta.stackexchange.com/questions/2950/   -  person CodeCaster    schedule 26.11.2013
comment
См. Сторона сервера проверки модели MVC4 в контроллере API, вы Придется реализовать проверку.   -  person CodeCaster    schedule 26.11.2013
comment
@CodeCaster, спасибо за указатель.   -  person Don 01001100    schedule 26.11.2013


Ответы (1)


edit: Я сделал вывод класса более конкретным и изменил код состояния. Я начал вносить эти изменения и позже увидел второй комментарий @ CodeCaster.

public class ModelStateValidFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    /// <summary>
    /// Before the action method is invoked, check to see if the model is
    /// valid.
    /// </summary>
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext p_context)
    {
        if (!p_context.ModelState.IsValid)
        {
            List<ErrorPart> errorParts = new List<ErrorPart>();

            foreach (var modelState in p_context.ModelState)
            {
                foreach (var error in modelState.Value.Errors)
                {
                    String message = "The request is not valid; perhaps it is not well-formed.";

                    if (error.Exception != null)
                    {
                        message = error.Exception.Message;
                    }
                    else if (!String.IsNullOrWhiteSpace(error.ErrorMessage))
                    {
                        message = error.ErrorMessage;
                    }

                    errorParts.Add(
                        new ErrorPart
                        {
                            ErrorMessage = message
                          , Property = modelState.Key
                        }
                    );
                }
            }

            throw new HttpResponseException(
                p_context.Request.CreateResponse<Object>(
                    HttpStatusCode.BadRequest
                  , new { Errors = errorParts }
                )
            );
        }
        else
        {
            base.OnActionExecuting(p_context);
        }
    }
}

исходный ответ: благодаря указателю от @CodeCaster я использую следующее, и, похоже, он работает:

/// <summary>
/// Throws an <c>HttpResponseException</c> if the model state is not valid;
/// with no validation attributes in the model, this will occur when the
/// input is not well-formed.
/// </summary>
public class ModelStateValidFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    /// <summary>
    /// Before the action method is invoked, check to see if the model is
    /// valid.
    /// </summary>
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext p_context)
    {
        if (!p_context.ModelState.IsValid)
        {
            throw new HttpResponseException(
                new HttpResponseMessage
                {
                    Content = new StringContent("The posted data is not valid; perhaps it is not well-formed.")
                  , ReasonPhrase = "Exception"
                  , StatusCode = HttpStatusCode.InternalServerError
                }
            );
        }
        else
        {
            base.OnActionExecuting(p_context);
        }
    }
}
person Don 01001100    schedule 26.11.2013
comment
Возможно, вы захотите вернуть более подробные ошибки (например, если оставлены обязательные поля null), и это не ошибка сервера, а ошибка клиента. 400 BadRequest может немного его скрыть. - person CodeCaster; 26.11.2013