.Net Core3.1跨平台实战4:AOP —— Filter
前言
说明:Asp.Net Core中的各种过滤器(授权、资源、操作、结果、异常)以及过滤器的注册方式
Asp.Net Core 3.1跨平台实战.视频学习笔记
1、AOP
(1)AOP全称Aspect Oriented Programming意为面向切面编程,也叫做面向方法编程,是通过预编译方式和运行期动态代理的方式实现不修改源代码的情况下给程序动态统一添加功能的技术。
(2)AOP技术利用一种称为“横切”的技术,剖解开封装对象的内部,将影响多个类的公共行为封装到一个可重用的模块中,并将其命名为Aspect切面。所谓的切面,简单来说就是与业务无关,却为业务模块所共同调用的逻辑,将其封装起来便于减少系统的重复代码,降低模块的耦合度,有利用未来的可操作性和可维护性。
(3)利用AOP可以对业务逻辑各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发效率。
(4)AOP的使用场景主要包括日志记录、性能统计、安全控制、事务处理、异常处理等。
2、五大过滤器
(1)Authonization Filter
- Authorization是五种Filter中优先级最高的,通常用于验证Request合不合法,不合法后面就直接跳过。
(2)Resource Filter
- Resource是第二优先,会在Authorization之后,Model Binding之前执行。通常会是需要对Model加工处理才用。
(3)Exception Filter
- 异常处理的Filter。
测试程序:
异常处理类
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
/// <summary>
/// 通过Execption Filter 过滤器可以进行全局的异常日志收集 等操作
/// </summary>
/// <param name="context"></param>
public override void OnException(ExceptionContext context)
{
if (!context.ExceptionHandled)
{
Console.WriteLine($"{context.HttpContext.Request.Path}:{context.Exception.Message}");
context.Result = new JsonResult(new
{
Result = true,
Msg = "发生异常"
});
}
context.ExceptionHandled = true;
}
}
控制器
public class FourController : Controller
{
//访问index时异常不会报错
[CustomExceptionFilterAttribute]
public IActionResult Index()
{
int i = 0;
int j = 5 / i;
return View();
}
//访问info时异常时会报错
public IActionResult Info()
{
int i = 0;
int j = 5 / i;
return View();
}
}
结果:
(4)Action Filter
- 最常使用的Filter,封包进出都会经过它,使用上没什么需要特别注意的。跟Resource Filter很类似,但并不会经过Model Binding。
(5)Result Filter
- 当Action完成后,最终会经过的Filter
为了更清楚的了解Filter的执行顺序,进行一下测试
过滤器类
/// <summary>
///行为过滤器:可以通过ActionFilter 拦截 每个执行的方法进行一系列的操作,比如:执行操作日志、参数验证,权限控制 等一系列操作。
/// </summary>
public class CustomActionFilterAttributecs : Attribute, IActionFilter, IFilterMetadata, IOrderedFilter
{
public int Order { get; set; }
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine($"This is {typeof(CustomActionFilterAttributecs)} OnActionExecuted");
}
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine($"This is {typeof(CustomActionFilterAttributecs)} OnActionExecuting");
}
}
/// <summary>
/// 结果过滤器:通过ResultFilter,可以对结果进行格式化、大小写转换等一系列操作
/// </summary>
public class CustomResultFilterAttributecs : Attribute, IResultFilter, IFilterMetadata, IOrderedFilter
{
public int Order { get; set; }
public void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine($"This is {typeof(CustomResultFilterAttributecs)} OnResultExecuted");
}
public void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine($"This is {typeof(CustomResultFilterAttributecs)} OnResultExecuting");
}
}
/// <summary>
/// 资源过滤器:通过Resource Filter 可以进行资源缓存、防盗链等操作
/// </summary>
public class CustomResourceFilterAttributecs : Attribute, IResourceFilter, IFilterMetadata, IOrderedFilter
{
public int Order { get; set; }
public void OnResourceExecuted(ResourceExecutedContext context)
{
Console.WriteLine($"This is {typeof(CustomResourceFilterAttributecs)} OnResourceExecuted");
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
Console.WriteLine($"This is {typeof(CustomResourceFilterAttributecs)} OnResourceExecuting");
}
}
/// <summary>
/// 权限控制过滤器 :通过 Authonization Filter 可以实现复杂的权限角色认证、登陆授权等操作
/// </summary>
public class CustomAuthonizationFilterAttributecs : Attribute, IAuthorizationFilter, IFilterMetadata, IOrderedFilter
{
public int Order => 1;
public void OnAuthorization(AuthorizationFilterContext context)
{
Console.WriteLine($"This is {typeof(CustomAuthonizationFilterAttributecs)} OnAuthorization");
}
}
控制器
[CustomActionFilterAttributecs]
[CustomResourceFilterAttributecs]
[CustomResultFilterAttributecs]
[CustomAuthonizationFilterAttributecs]
public IActionResult Index()
{
Console.WriteLine("This is Index Action");
return View();
}
结果
3、过滤器的注册方式
(1)Action 注册方式
Action 注册方式是局部注册方式,针对控制器中的某个方法上标注特性的方式进行注册,代码如下:
[CustomAuthonizationFilterAttributecs]
public IActionResult Index()
{
return View();
}
(2)Controller 注册方式
了解过Action 特性注册方式的同学,一定发现了它的不好之处就是我一个控制器里面需要使用同一套Filter 的时候,需要一个一个Action 标注特性注册,是不是很繁琐呢?有没有其他方式进行代替这些繁琐的操作呢?微软给我们提供了简便的控制器标注注册方式,代码如下:
[CustomAuthonizationFilterAttributecs]
public class FirstController : Controller
{
private ILogger<FirstController> _logger;
public FirstController(ILogger<FirstController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
}
(3)全局注册方式
现在有些同学考虑了一些全局的情况,比如我要全局处理系统中的异常,或者收集操作日志等,需要全局注册一个ExceptionFilter 来实现,就不需要每一个Controller 中进行代码注册,方便快捷。代码如下:
StartUp.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(opt =>
{
//全局注册授权过滤器(以下两种都可以)
opt.Filters.Add(typeof(CustomAuthonizationFilterAttributecs));
//opt.Filters.Add(new CustomAuthonizationFilterAttributecs());
});
}
(4)TypeFilter 和 ServiceFilter 注册方式
① ServiceFilterAttribute:首先在控制器或action上追加属性, 然后在 ConfigureService中对该类进行注册一下, 如: services.AddScoped();
[ServiceFilter(typeof(CustomAuthonizationFilterAttributecs))] //需要在ConfigureService中对该类进行注册
public IActionResult MyTestA()
{
base.ViewBag.Now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
return View();
}
StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching();
services.AddSession();
services.AddControllersWithViews();
services.AddScoped<CustomAuthonizationFilterAttributecs>();//追加慈行代码
}
② TypeFilterAttribute: 在控制器或action上追加属性即可,如下面的Index,不需要再在ConfigureService中进行注册了, 相比上面的ServiceFilterAttribute更方便。
[TypeFilter(typeof(CustomAuthonizationFilterAttributecs))] //不需要再在ConfigureService中进行注册了
public IActionResult MyTestA()
{
base.ViewBag.Now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
return View();
}
参考链接
(1)Asp.Net Core中的各种过滤器(授权、资源、操作、结果、异常)
(2)Asp.Net Core Filter 深入浅出的那些事-AOP