I'm using ASP.NET's ApiController
class to create a Web API. I find that if I pass invalid JSON, instead of the caller getting a 500, the input parameter is null. As in, if I pass
{ "InputProperty:" "Some Value" }
which is clearly not valid, to this method:
[HttpPost]
public Dto.OperationOutput Operation(Dto.OperationInput p_input)
{
return this.BusinessLogic.Operation(p_input);
}
I get that p_input
is null
. I'd rather send something back telling the user they didn't POST valid JSON.
In my WebApiConfig.cs
, I have:
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
config.Formatters.XmlFormatter.UseXmlSerializer = true;
Any ideas? I did see this example, but I believe that's ASP.NET MVC, not ApiController.
edit: I've made the output from the class a little more specific and changed the status code. I'd started making these changes and later saw @CodeCaster's second comment.
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);
}
}
}
original answer:
Thanks to a pointer from @CodeCaster, I am using the following, and it seems to work:
/// <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);
}
}
}