简介
Action过滤器将在controller的Action执行之前和之后执行相应的方法。
实现一个自定义Action过滤器
自定义一个全局异常过滤器需要实现IActionFilter接口
public class ActionFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("action执行之后");
}
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("action执行之前");
}
}
IActionFilter需要实现两个方法OnActionExecuted,OnActionExecuting。OnActionExecuting将在Action之前执行,OnActionExecuted在Action之后执行。
知道原理之后我们们就可以利用其特性来简化我们的代码,在MVC中一个重要的概念就时Model验证,我们定义Model约束,然后在Action中验证Model是否绑定成功,我们的Action中重复地写如下代码
[HttpGet]public ActionResult Get() {
if (!ModelState.IsValid)
return BadRequest("参数错误!");
}
这样重复的代码不仅增加代码复杂都也不美观,我们可以在ActionFilter中自动完成
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid) return;
var modelState = context.ModelState.FirstOrDefault(f => f.Value.Errors.Any());
string errorMsg = modelState.Value.Errors.First().ErrorMessage;
throw new AppException(errorMsg);
}
当Model绑定错误时,我们抛出异常信息,并在上一章节的异常过滤器ExceptionFilter中捕获,返回错误信息给请求方。
我们也可以利用ActionFilter的特性来记录Action的执行时间,当Action执行时间过慢时输出警告日志
public class ActionFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
var httpContext = context.HttpContext;
var stopwach = httpContext.Items[Resources.StopwachKey] as Stopwatch;
stopwach.Stop();
var time = stopwach.Elapsed;
if (time.TotalSeconds > 5)
{
var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>();
var logger = factory.CreateLogger<ActionExecutedContext>();
logger.LogWarning($"{context.ActionDescriptor.DisplayName}执行耗时:{time.ToString()}");
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
var stopwach = new Stopwatch();
stopwach.Start();
context.HttpContext.Items.Add(Resources.StopwachKey, stopwach);
}
}