首先代码如下
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
#region Identity
private readonly ILogger<CustomExceptionFilterAttribute> _logger;
private readonly IModelMetadataProvider _modelMetadataProvider;
public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger
, IModelMetadataProvider modelMetadataProvider)
{
this._modelMetadataProvider = modelMetadataProvider;
this._logger = logger;
}
#endregion
/// <summary>
/// 异常发生,但是没有处理时
/// 异常之后得写日志
/// </summary>
/// <param name="context"></param>
public override void OnException(ExceptionContext context)
{
if (!context.ExceptionHandled)
{
this._logger.LogError($"{context.HttpContext.Request.RouteValues["controller"]} is Error");
if (this.IsAjaxRequest(context.HttpContext.Request))//header看看是不是XMLHttpRequest
{
context.Result = new JsonResult(new
{
Result = false,
Msg = context.Exception.Message
});//中断式---请求到这里结束了,不再继续Action
}
else
{
var result = new ViewResult { ViewName = "~/Views/Shared/Error.cshtml" };
result.ViewData = new ViewDataDictionary(_modelMetadataProvider, context.ModelState);
result.ViewData.Add("Exception", context.Exception);
context.Result = result;
}
context.ExceptionHandled = true;
}
}
private bool IsAjaxRequest(HttpRequest request)
{
string header = request.Headers["X-Requested-With"];
return "XMLHttpRequest".Equals(header);
}
}
[ServiceFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
return View();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(typeof(CustomExceptionFilterAttribute));//不是直接new 而是容器生成 就可以自动注入了
}
[TypeFilter(typeof(CustomExceptionFilterAttribute))]
public IActionResult Index()
{
return View();
}
自定义实现
/// <summary>
/// 基于完成Filter的依赖注入
/// </summary>
public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory
{
private readonly Type _FilterType = null;
public CustomIOCFilterFactoryAttribute(Type type)
{
this._FilterType = type;
}
public bool IsReusable => true;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
//return (IFilterMetadata)serviceProvider.GetService(typeof(CustomExceptionFilterAttribute));
return (IFilterMetadata)serviceProvider.GetService(this._FilterType);
}
}
使用
[CustomIOCFilterFactoryAttribute(typeof(CustomExceptionFilterAttribute))]/
public IActionResult Index()
{
return View();
}
public class CustomActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
//告诉浏览器缓存(新开页面,刷新并不会),浏览器不同会有不同效果
context.HttpContext.Response.Headers.Add("Cache-Control", "public,max-age=6000");
Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuted{this.Order}");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnActionExecuting{this.Order}");
}
public override void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuting{this.Order}");
}
public override void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine($"This {nameof(CustomActionFilterAttribute)} OnResultExecuted{this.Order}");
}
}
public class CustomControllerFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuted {this.Order}");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnActionExecuting{this.Order}");
}
public override void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuting{this.Order}");
}
public override void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine($"This {nameof(CustomControllerFilterAttribute)} OnResultExecuted{this.Order}");
}
}
public class CustomGlobalFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuted{this.Order}");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnActionExecuting{this.Order}");
}
public override void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuting{this.Order}");
}
public override void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine($"This {nameof(CustomGlobalFilterAttribute)} OnResultExecuted{this.Order}");
}
}
/// <summary>
/// 全局---控制器---Action Order默认0,从小到大执行 可以负数
/// </summary>
/// <returns></returns>
[CustomActionFilterAttribute(Order = 10)]
[CustomActionFilterAttribute]
[CustomActionCacheFilterAttribute(Order = -1)]
public IActionResult Info()
{
Console.WriteLine($"This is {nameof(ThirdController)} Info");
base.ViewBag.Now = DateTime.Now;
Thread.Sleep(2000);
return View();
}
// <summary>
///
/// </summary>
public class CustomResourceFilterAttribute : Attribute, IResourceFilter, IFilterMetadata
{
private static Dictionary<string, IActionResult> CustomCache = new Dictionary<string, IActionResult>();
/// <summary>
/// 发生在其他动作之前
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuting(ResourceExecutingContext context)
{
Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuting");
//if 有缓存,直接返回缓存
string key = context.HttpContext.Request.Path;
if (CustomCache.ContainsKey(key))
{
context.Result = CustomCache[key];//断路器--到Result生成了,但是Result还需要转换成Html
}
}
/// <summary>
/// 发生在其他动作之后
/// </summary>
/// <param name="context"></param>
public void OnResourceExecuted(ResourceExecutedContext context)
{
Console.WriteLine($"This is {nameof(CustomResourceFilterAttribute) }OnResourceExecuted");
//这个应该缓存起来
string key = context.HttpContext.Request.Path;
if (!CustomCache.ContainsKey(key))
{
CustomCache.Add(key, context.Result);
}
}
}
[CustomResourceFilterAttribute]//缓存了变量
public IActionResult Info()
{
Console.WriteLine($"This is {nameof(ThirdController)} Info");
base.ViewBag.Now = DateTime.Now;
Thread.Sleep(2000);
return View();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddControllersWithViews(
options =>
{
options.Filters.Add<CustomExceptionFilterAttribute>();//全局注册
options.Filters.Add<CustomGlobalFilterAttribute>();
});
}