[SOLVED] Inconsistent error response in .NET 6 Web API application

Issue

I am not able to find how to throw exceptions as they are generated by .NET 6 Web API.
If I return BadRequest(ModelState) with added errors I am not getting same message with status, type, title etc.
By default .NET generates this kind of errors when validation error occurs:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-488f8c0057223cbba92fc1fbfc8865d8-2341d7aba29d098f-00",
"errors": {
    "$": [
        "The JSON object contains a trailing comma at the end which is not supported in this mode. Change the reader options. Path: $ | LineNumber: 7 | BytePositionInLine: 0."
    ],
    "model": [
        "The model field is required."
    ]
}

}

I want to configure my application to respond with the same error JSON, or I want to configure so it will respond with the custom JSON fields.

I tried to add a middleware that will catch exceptions, but it does not handle model errors (which are handled by framework by itself). How can I handle errors globally, or how can I throw exceptions that will be treated the same as framework handles them? Any documentation/tutorial links are welcome!

Solution

You can disable default bad request responses like the following code:

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
     options.SuppressModelStateInvalidFilter = true;
});

So you can return any model you want in BadRequest.
However, you then have to do the model validation yourself in each endpoint like:

[HttpPost(Name = "Post1")]
public IActionResult Post1(Model1 model)
{
    if (!ModelState.IsValid)
        return BadRequest(new CustomApiResponse());
   ...
}

[HttpPost(Name = "Post2")]
public IActionResult Post2(Model2 model)
{
    if (!ModelState.IsValid)
        return BadRequest(new CustomApiResponse());
   ...
}

If you want to return a global JSON structure, you can create a filter with the ActionFilterAttribute and use it for all your endpoints so you don’t need to do model validation on every endpoint.

Custom Validation Filter:

public class CustomValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(new GlobalApiResponse());
        }

        base.OnActionExecuting(context);
    }
}

You need to register your custom filter in Program.cs

builder.Services.AddControllers(options =>
{
    options.Filters.Add(typeof(CustomValidationFilterAttribute));
});

This is just one of the ways you can use to achieve what you want, you can find different methods on the internet.

Answered By – Burhan Savci

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *