Intercept bad requests before reaching controller in ASP.NET Core

谁说胖子不能爱 提交于 2019-12-17 06:54:46

问题


I have a logic to apply in case the request received is a BadRequest, to do this I have created a filter:

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            // Apply logic
        }
    }
}

In Startup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => { options.Filters.Add<ValidateModelAttribute>(); });
}

Controller:

[Route("api/[controller]")]
[ApiController]
public class VerifyController : ControllerBase
{
    [Route("test")]
    [HttpPost]
    [ValidateModel]
    public ActionResult<Guid> validationTest(PersonalInfo personalInfo)
    {
        return null;
    }
}

Model:

public class PersonalInfo
{
    public string FirstName { get; set; }
    [RegularExpression("\\d{4}-?\\d{2}-?\\d{2}", ErrorMessage = "Date must be properly formatted according to ISO 8601")]
    public string BirthDate { get; set; }
}

The thing is when I put a break point on the line:

if (!context.ModelState.IsValid)

execution reaches this line only if the request I send is valid. Why it is not passing the filter if I send a bad request?


回答1:


The [ApiController] attribute that you're applying to your controller adds "Automatic HTTP 400 Responses" to your MVC pipeline, which means that your custom filter and action will not be executed if ModelState is invalid. You have a few options for affecting how this works:

1. Remove the [ApiController] attribute

Although you can just remove the [ApiController] attribute, this would also cause the loss of some of the other features it provides, such as "Binding source parameter inference".

2. Disable only the Automatic HTTP 400 Responses

Here's an example from the docs that shows how to disable just this feature:

services.Configure<ApiBehaviorOptions>(options =>
{
    // ...
    options.SuppressModelStateInvalidFilter = true;
});

This code goes inside of your Startup's ConfigureServices method.

3. Customise the automatic response that gets generated

If you just want to provide a custom response to the caller, you can customise what gets returned. I've already described how this works in another answer, here.




回答2:


As the attribute filter in the life cycle of the .Net Core you can’t handle it. The filter layer with ModelState will run after the model binding.

You can handle it with .Net Core middleware as the following https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1&tabs=aspnetcore2x



来源:https://stackoverflow.com/questions/51870603/intercept-bad-requests-before-reaching-controller-in-asp-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!