skip to Main Content

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!

2

Answers


  1. 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.

    Login or Signup to reply.
  2. In .Net6 Web Api, If You Want To Validate Model By Your Code, And You Can Debug It, Just Do This:

    public class ModelValidationFilterAttribute : ActionFilterAttribute
    {
        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (!context.ModelState.IsValid)
            {
                context.Result = new BadRequestObjectResult(new BaseResponse() { code = ResponseCode.失败, msg = "" });
            }
            return base.OnActionExecutionAsync(context, next);
        }
    }
    

    Then Do It In The Program.cs

    // Add services to the container.
    builder.Services.AddControllers(options =>
    {
        //Add Your Filter
        options.Filters.Add<ModelValidationFilterAttribute>();
    }).ConfigureApiBehaviorOptions(options =>
    {
        //Disable The Default
        options.SuppressModelStateInvalidFilter = true;
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search