简体   繁体   中英

Overriding BadRequest response in ASP.NET Core ResourceFilter

I am implementing a resource filter to store invalid requests in database and override returned BadRequest response.

I stored invalid requests successfully but I am struggling with overriding response, I tried the following:

public class MyFilter : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        ;
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        if (!context.ModelState.IsValid)
        {
            //store request in data base
            context.Result= new BadRequestObjectResult(new MyErrorModel(){ID = "1",FriendlyMessage = "Your request was invalid"});
        }
    }
}

public class MyErrorModel
{
    public string FriendlyMessage { get; set; }
    public string ID { get; set; }
}

But the returned response is not being overridden. Is there a way to override the response inside Resource filters?

PS: I am using [ApiController] attribute.

As we all kown , the IResourceFilter runs immediately after the authorization filter and is suitable for short-circular .

However , you will make no influence on the result by setting Result=new BadRequestObjectResult() when the result execution has finished .

See the workflow as below :

在此处输入图片说明

According to the workflow above , we should run the MyFilter after the stage of model binding and before the stage of result filter . In other words , we should put the logic into a action filter . Since there's already a ActionFilterAttribute out of box , just create a MyFilterAttribute which inherits from the ActionFilterAttribute :

public class MyFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            //store request in data base
            context.Result = new BadRequestObjectResult(new MyErrorModel() { ID = "1", FriendlyMessage = "Your request was invalid" });
        }
    }
}

Here's a screenshot the filter works :

在此处输入图片说明

[Edit]:

The code of controller decorated with [ApiController] :

namespace App.Controllers
{
    [ApiController]
    [Route("Hello")]
    public class HelloController : Controller
    {
        [MyFilter]
        [HttpGet("index")]
        public IActionResult Index(int x)
        {
            var y =ModelState.IsValid;
            return View();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM