我正在实现一个资源过滤器来存储数据库中的无效请求并覆盖返回的BadRequest响应。
我成功地存储了无效请求,但我正在努力克服覆盖响应,我尝试了以下方法:
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; }
}
但是返回的响应没有被覆盖。有没有办法覆盖资源过滤器内的响应?
P.S:我正在使用[ApiController]属性。
众所周知,IResourceFilter
在授权过滤器后立即运行,适用于短循环。
但是,通过在结果执行完成时设置Result=new BadRequestObjectResult()
,您不会对结果产生任何影响。
请参阅以下工作流程:
根据上面的工作流程,我们应该在模型绑定阶段之后和结果过滤阶段之前运行MyFilter
。换句话说,我们应该将逻辑放入动作过滤器中。由于已经有一个开箱即用的ActionFilterAttribute
,只需创建一个继承自MyFilterAttribute
的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" });
}
}
}
这是过滤器的截图:
[编辑]:
用[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();
}
}
}