Custom result filter vs InvalidModelStateResponseFactory in ASP.NET Core 6.0

451 Views Asked by At

I can use a custom result filter inherited by IResultFilter to return response in case of a model-validation failure:

public class FailedValidationResultFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.ModelState.IsValid)
            return;

        //other logic to create the ProblemDetails response
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
    }
}

Or I can use this in Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddControllers();
builder.Services
    .Configure<ApiBehaviorOptions>(x => x.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult(););

ValidationProblemDetailsResult:

public class ValidationProblemDetailsResult : IActionResult
{
    public async Task ExecuteResultAsync(ActionContext context)
    {
        //logic here and then followed by this:
        var problemDetails = new ProblemDetails
        {
            Type = "",
            Title = "Invalid parameters",
            Status = StatusCodes.Status400BadRequest,
            Detail = "Your request parameters didn't validate.",
            Instance = "",
            //Extensions = 
        };

        var objectResult = new ObjectResult(problemDetails) { StatusCode = problemDetails.Status };
        await objectResult.ExecuteResultAsync(context);
    }
}

Question: which one should I prefer and why? Also, please provide scenario(s), to better understand their uses/pros and cons.

1

There are 1 best solutions below

0
Ruikai Feng On

In WeiApi projects,the [ApiController] attribute makes model validation errors automatically trigger an HTTP 400 response.

and your codes

builder.Services
    .Configure<ApiBehaviorOptions>(x => x.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult();); 

replaced the default BadrequestResult with your custom result,when it trigger 400 resopnse automaticlly(In an other words,it works only when your controller is attached with [ApiController] attribute and applied to all actions in the controller ) ,you could check this document related

With a filter,you could choose to apply it to certain controller/action or all actions whenever the controller is attached with ApiControoler Attribute or not,the document related