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)