Search code examples
c#json.net-core.net-5json-serialization

Custom error response for incorrect json. Dotnet Core Web API


Is there a mechanism for returning a custom error response if an invalid type is given to a WebApi in Dotnet Core?

E.G.

if I have a class that looks like this

public class SomeApiClass
{
    public int Id { get; set; }
}

But make a post request like this (notice that I'm expecting an int and giving a string):

{
    "id": "f"
}

Then the standard dotnet response looks like this:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-27be45d9cffab14698524a63120a4f88-6bfe2613f2328a42-00",
    "errors": {
        "$.id": [
            "The JSON value could not be converted to System.Int64. Path: $.wmdaid | LineNumber: 1 | BytePositionInLine: 15."
        ]
    }
}

However, I'd like all my responses to look the same for bad requests so that anybody implementing the API can always get a consistent JSON back. My problem being the JSON deserialisation is being done before the controller validation.

So, in a nutshell, Is it possible to change this response format as a part of the dotnet middleware?


Solution

  • You can use custom ActionFilter.

    public class ReformatValidationProblemAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (context.Result is BadRequestObjectResult badRequestObjectResult)
                if (badRequestObjectResult.Value is ValidationProblemDetails)
                {
                    context.Result = new BadRequestObjectResult("Custom Result Here");
                }
    
            base.OnResultExecuting(context);
        }
    }
    

    Controller.cs

    [ApiController]
    [ReformatValidationProblem]
    public class Controller : ControllerBase
    { 
        ...
    }
    

    or register it globally Startup.cs

    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(ReformatValidationProblemAttribute));
    });