.NET5 AOP 5个Filter
AOP: 可以往不修改之前的代码为基础,可以动态的增加新功能; |
AuthorizationFilte r鉴权授权
ResourceFilter 资源
ExceptionFilter 异常
ActionFilter 方法
ResultFilter 结果
ActionFilter的特点
自定义一个CustomActionfilterAttribute特性,继承Atribute, 实现IActionFilter接口; 实现方法,标记在Action, 上;
请求标记的有CustomActionFilterAttribute的Action:执行顺序如下:
1.执行控制器构造函数
2.执行CustomActionfiterAttribute内的OnActionExecutind方法
3.执行Action
4.执行CustomActionFilterAttribute内的OnActionExecuted
public class CustomActionFilterAttribute : Attribute, IActionFilter
{
/// <summary>
/// 方法执行后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("CustomActionFilterAttribute.OnActionExecuted");
}
/// <summary>
/// 方法执行前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("CustomActionFilterAttribute.OnActionExecuting");
}
}
使用
ActionFilter的多种使用
1.通过实现IActionFilter接口来完成扩展
public class CustomActionFilterAttribute : Attribute, IActionFilter
{
/// <summary>
/// 方法执行后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("CustomActionFilterAttribute.OnActionExecuted");
}
/// <summary>
/// 方法执行前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("CustomActionFilterAttribute.OnActionExecuting");
}
}
2.通过继承ActionfilterAttribute (系统提供的实现),根据自己的需要,覆写不同的方法,达到自己的诉求
public class CustomActionFilterChildAttribute:ActionFilterAttribute
{
/// <summary>
/// 方法执行后
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("CustomActionFilterChildAttribute.OnActionExecuted");
}
/// <summary>
/// 方法执行前
/// </summary>
/// <param name="context"></param>
public override void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("CustomActionFilterChildAttribute.OnActionExecuting");
}
}
3.异步版本的实现,通过实现IAsynCActionFilter接口来实现
public class CustomActionFilterAsyncAttribute : Attribute ,IAsyncActionFilter
{
/// <summary>
/// 异步版本
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
return Task.Run(()=>
{
Console.WriteLine("CustomActionFilterAsyncAttribute .OnActionExecutionAsync");
});
}
}
ActionFilter 应用
1.记录日志,action比较靠近Action,日志记录,可以记录到Action内部做的一些处理
1).引入log4net包
2).新建一个名为log4net.config配置文件
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--log4net配置参数-->
<log4net>
<appender name="RollingAppender" type="log4net.Appender.RollingFileAppender">
<!--指定日志文件保存的目录-->
<file value="Logs\"/>
<!--追加日志内容-->
<appendToFile value="true"/>
<!--可以为:Once|Size|Date|Composite-->
<!--Compoosite为Size和Date的组合-->
<rollingStyle value="Composite"/>
<!--设置为true,当前最新日志文件名永远为file字节中的名字-->
<staticLogFileName value="false"/>
<!--当备份文件时,备份文件的名称及后缀名-->
<datePattern value="yyyy-MM-dd'.log'"/>
<!--日志最大个数-->
<!--rollingStyle节点为Size时,只能有value个日志-->
<!--rollingStyle节点为Composie时,每天有value个日志-->
<maxSizeRollBackups value="20"/>
<!--可用的单位:KB|MB|GB-->
<maximumFileSize value="5MB"/>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ALL"/>
<param name="LevelMax" value="FATAL"/>
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<root>
<priority value="ALL"/>
<level value="ALL"/>
<appender-ref ref="RollingAppender"/>
</root>
</log4net>
</configuration>
3).startup.cs注册
//为StartUp.cs添加属性
public static ILoggerRepository repository { get; set; }
public IConfiguration Configuration { get; } //构造函数注入:Configuration用于读取配置文件的
public Startup(IConfiguration configuration)
{
Configuration = configuration;
repository = LogManager.CreateRepository("WFCore"); //我的项目名称叫WFCore
string path = AppDomain.CurrentDomain.BaseDirectory + @"\CfgFile\log4net.config";
XmlConfigurator.Configure(repository, new FileInfo(path)); //指定配置文件
}
4).应用
ActionFController
public class ActionFController:Controller
{
private ILog log;
public ActionFController()
{
this.log = LogManager.GetLogger(Startup.repository.Name, typeof(ActionFController));
Console.WriteLine("ActionFController被构造了");
}
//[CustomActionFilterAttribute]
[TypeFilter(typeof(CustomActionFilterAttribute))]//可以支持依赖注入
public IActionResult Index()
{
log.Info("Action used");
return View();
}
}
CustomActionFilterAttribute
public class CustomActionFilterAttribute : Attribute, IActionFilter
{
private ILog log;
public CustomActionFilterAttribute()
{
this.log = LogManager.GetLogger(Startup.repository.Name, typeof(CustomActionFilterAttribute));
}
/// <summary>
/// 方法执行后
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
///记录请求来了之后的一些多数:
//参数Newtonsoft.Json.JsonConvert.SerializeObject(context.HttpContext.Request.Query);
// log4net;
log.Info(Newtonsoft.Json.JsonConvert
.SerializeObject(context.HttpContext.Request.Query));
log.Info("CustomActionFilterAttribute.OnActionExecuted");
}
/// <summary>
/// 方法执行前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
log.Debug(Newtonsoft.Json.JsonConvert
.SerializeObject(context.Result));
log.Debug("CustomActionFilterAttribute.OnActionExecuting");
}
}
Filter的多种注册和扩展
1.[CustomActionFilter]---Fitler必须有无参数构造函数
2.[TypeFilter(typeof(CustomActionFilterAttribute))],可以没有无参数构造函数,可以支持依赖注入
3.[ServiceFilter(lypeofCustomActionFilterAttribute)],可以没有无参数构造函数,可以支持依赖注入,但是必须要注册服务
FilterFactory扩展定制
1. CustomFilterFactory类实现IFilterFactory接口
public class CustomFilterFactory : Attribute, IFilterFactory
{
private readonly Type _type=null;
public CustomFilterFactory(Type type)
{
_type = type;
}
public bool IsReusable => true;
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
object oInstance =serviceProvider.GetService(_type);
return (IFilterMetadata)oInstance;
}
}
2.应用
public class ActionFController:Controller
{
[CustomFilterFactory(typeof(CustomActionFilterAttribute))]
public IActionResult Index()
{
return View();
}
}