在到达ASP.NET Core中的控制器之前拦截错误请求

时间:2018-08-16 06:09:32

标签: c# asp.net-core asp.net-core-mvc

如果收到的请求是BadRequest,我有一个逻辑可以应用,为此,我创建了一个过滤器:

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

在启动中:

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

控制器:

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

型号:

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; }
}

问题是当我在行上放置一个断点时:

if (!context.ModelState.IsValid)
仅当我发送的请求有效时,执行才会到达此行。如果我发送了错误的请求,为什么它没有通过过滤器?

2 个答案:

答案 0 :(得分:4)

您要应用到控制器的[ApiController]属性会在MVC管道中添加“自动HTTP 400响应”,这意味着如果ModelState无效,则不会执行自定义过滤器和操作。您可以通过几种方法来影响其工作方式:

1。删除[ApiController]属性

尽管您只可以删除[ApiController]属性,但这也会导致其提供的其他一些功能丢失,例如“绑定源参数推断”。

2。禁用自动HTTP 400响应

这是docs中的示例,显示了如何仅禁用此功能:

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

此代码位于您的Startup的{​​{1}}方法中。

3。自定义生成的自动响应

如果只想向调用者提供自定义响应,则可以自定义返回的内容。我已经在另一个答案here中描述了它的工作原理。

答案 1 :(得分:0)

作为.Net Core生命周期中的属性过滤器,您无法处理。具有ModelState的筛选器层将在模型绑定之后运行。

您可以使用.Net Core中间件来处理它,如下所示:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1&tabs=aspnetcore2x