I.はじめに
共有ASP.NETコアフィルター使用前に、およそレットの話AOP
AOPは、それが何でありますか?
AOP
フルネームのAspect Oriented Programming
も方法指向プログラミングとして知られている手段指向プログラミングは、事前にコンパイルの方法とエージェントがプログラムを動的統一技術に機能を追加するためにソースコードを変更しない実行時の動的な方法で実施する場合です。
「クロス」技術、パッケージ内部断面アンロックオブジェクトとして知られている技術を使用してAOPは、一般的な行動への影響は、再利用可能なモジュールの複数のクラスにカプセル化し、名前Aspect
セクション。いわゆるカット面は、関係なく、サービスの単純で、それはコードの重複カプセル化されたシステムの低減を促進サービスと呼ばれる共通の論理モジュールであり、結合モジュールを低減し、将来の操作性および保守の使用。
開発効率を向上させつつAOPは、プログラムの再利用性を向上させ、それによって部品間の結合の程度を減少させる、ビジネス・ロジック、ビジネス・ロジックの各部分を分離するために使用することができます。
AOP使用シナリオは、ロギング、パフォーマンス統計、セキュリティ管理、トランザクション処理、例外処理が含まれます。
二、フィルタ - フィルタ
フィルタは、許可フィルタ、リソースフィルター、アクションフィルタ、それぞれ、フィルタの5を保持し、ASP.NET MVC製品の継続である 、例外フィルタと結果フィルター。
効果的にこの記事のお得な情報を紹介異なるフィルター、フィルターを通して作品ASP.NETコアの5種類の着信および発信パケットの処理を扱うことができます。
2.1フィルターの紹介
ASP.NETコアフィルターは、次の5つを使用することができます。
- フィルター認証:
認証は一般的に一緒に不正な要求を検証するために使用される5つのフィルターで最も優先度の高い、ですが、戻ってスキップすることは違法です。 - リソースフィルタ:リソースは次の優先順位で、モデルが承認した後にバインドする前に実行されます。モデルは、通常、使用前に処理するために必要とされます。
- 例外フィルタ:フィルタの例外処理。
- アクションフィルタ:フィルタは、最も一般的に使用され、パケットのうち、それを介して使用することに特別な注意を払う必要が行きません。リソースフィルタではなく、結合モデルを通じて、非常によく似ています。
- フィルター結果:アクションが完了すると、最終的にフィルターを通過します。
第三に、5つのフィルターの適用
この章では、5つのフィルタのAsp.Netコアの使用を説明し、実装する主です。
3.1 Authonizationフィルター
アクセス制御フィルタは
複素フィルタAuthonizationによって達成することができる权限角色认证
、登陆授权
およびその他の動作は
次のように実施例コードを実現しました。
public class AuthonizationFilter :Attribute,IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
//这里可以做复杂的权限控制操作
if (context.HttpContext.User.Identity.Name != "1") //简单的做一个示范
{
//未通过验证则跳转到无权限提示页
RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null);
context.Result = content;
}
}
}
3.2リソースフィルター
リソースフィルタは、
フィルタリソースによって実行されてもよい资源缓存
、防盗链
およびその他の操作。
IResourceFilterを達成するために必要な使用リソースフィルター抽象インタフェース
public class ResourceFilter : Attribute,IResourceFilter
{
public void OnResourceExecuted(ResourceExecutedContext context)
{
// 执行完后的操作
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
// 执行中的过滤器管道
}
}
3.3例外フィルタ
あなたは、フィルタの通過Execptionフィルターをグローバルできる异常日志收集
操作。
使用Execption Filter 要求实现IExceptionFilter
抽象接口
IExceptionFilter
接口会要求实现OnException
方法,当系统发生未捕获异常时就会触发这个方法。OnException
方法有一个ExceptionContext
异常上下文,其中包含了具体的异常信息,HttpContext及mvc路由信息。系统一旦出现未捕获异常后,比较常见的做法就是使用日志工具,将异常的详细信息记录下来,方便修正调试。下面是日志记录的实现。
public class ExecptionFilter : Attribute, IExceptionFilter
{
private ILogger<ExecptionFilter> _logger;
//构造注入日志组件
public ExecptionFilter(ILogger<ExecptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
//日志收集
_logger.LogError(context.Exception, context?.Exception?.Message??"异常");
}
}
3.4 Action Filter
作用:可以通过ActionFilter 拦截 每个执行的方法进行一系列的操作,比如:执行操作日志
、参数验证
,权限控制
等一系列操作。
使用Action Filter 需要实现IActionFilter 抽象接口,IActionFilter
接口要求实现OnActionExecuted
和OnActionExecuting
方法
public class ActionFilter : Attribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
//执行完成....
}
public void OnActionExecuting(ActionExecutingContext context)
{
//执行中...
}
}
3.5 Result Filter
结果过滤器,可以对结果进行格式化、大小写转换等一系列操作。
使用Result Filter 需要实现IResultFilter 抽象接口,接口要求实现
OnResultExecuting
方法 和OnResultExecuted
方法
OnResultExecuting
:Called before the action result executes. 在操作结果执行之前调用OnResultExecuted
:Called after the action result executes. 在操作结果执行之后调用
具体代码实现代码如下:
public class ResultFilter : Attribute, IResultFilter
{
public void OnResultExecuted(ResultExecutedContext context)
{
// 在结果执行之后调用的操作...
}
public void OnResultExecuting(ResultExecutingContext context)
{
// 在结果执行之前调用的一系列操作
}
}
四、Asp.Net Core 过滤器的注册方式
这一篇章主要来分析探讨Asp.Net Core 中过滤器
的三种注册方式Action
、Controller
、全局
。
4.1 Action 注册方式
Action 注册方式是局部注册方式,针对控制器中的某个方法上标注特性的方式进行注册,代码如下:
[AuthonizationFilter()]
public IActionResult Index()
{
return View();
}
4.2 Controller 注册方式
了解过Action 特性注册方式的同学,一定发现了它的不好之处就是我一个控制器里面需要使用同一套Filter 的时候,需要一个一个Action 标注特性注册,是不是很繁琐呢?有没有其他方式进行代替这些繁琐的操作呢?微软给我们提供了简便的控制器标注注册方式,代码如下:
[AuthonizationFilter()]
public class FirstController : Controller
{
private ILogger<FirstController> _logger;
public FirstController(ILogger<FirstController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
}
4.3 全局注册方式
现在有些同学考虑了一些全局的情况,比如我要全局处理系统中的异常,或者收集操作日志等,需要全局注册一个ExceptionFilter
来实现,就不需要每一个Controller 中进行代码注册,方便快捷。代码如下:
public void ConfigureServices(IServiceCollection services)
{
//全局注册异常过滤器
services.AddControllersWithViews(option=> {
option.Filters.Add<ExecptionFilter>();
});
services.AddSingleton<ISingletonService, SingletonService>();
}
4.4 TypeFilter 和 ServiceFilter 注册方式
上面的五大过滤器中事例代码中其中有一个过滤器的代码比较特,再来回顾ExceptionFilter
过滤器的实现代码:
public class ExecptionFilter : Attribute, IExceptionFilter
{
private ILogger<ExecptionFilter> _logger;
//构造注入日志组件
public ExecptionFilter(ILogger<ExecptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
//日志收集
_logger.LogError(context.Exception, context?.Exception?.Message??"异常");
}
}
从上面的代码中可以发现 ExceptionFilter 过滤器实现中存在日志服务的构造函数的注入,也就是说该过滤器依赖于其他的日志服务,但是日志服务都是通过DI 注入进来的;再来回顾下上面Action 注册方式或者Controller 注册方式 也即Attribute
特性标注注册方式,本身基础的特性是不支持构造函数的,是在运行时注册进来的,那要解决这种本身需要对服务依赖的过滤器需要使用 TypeFilter
或者ServiceFilter
方式进行过滤器的标注注册。
TypeFilter
和ServiceFilter
的区别。
- ServiceFilter和TypeFilter都实现了IFilterFactory
- ServiceFilter需要对自定义的Filter进行注册,TypeFilter不需要
- ServiceFilter的Filter生命周期源自于您如何注册,而TypeFilter每次都会创建一个新的实例
TypeFilter 使用方式
代码如下:
[TypeFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
return View();
}
通过上面的代码可以发现AuthonizationFilter 是默认的构造器,但是如果过滤器中构造函数中存在参数,需要注入服务那该怎么办呢?,比如上面的ExceptionFilter 代码,就不能使用这种方式进行注册,需要使用服务特性的方式,我们可以选择使用 代码如下:
[TypeFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
return View();
}
ServiceFilter 使用方式
控制器中的代码如下:
[ServiceFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
return View();
}
注册服务的代码如下:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("ConfigureServices");
services.AddControllersWithViews();
//services.AddControllersWithViews(option=> {
// option.Filters.Add<ExecptionFilter>();
//});
//注册过滤器服务,使用ServiceFilter 方式必须要注册 否则会报没有注册该服务的相关异常
services.AddSingleton<ExecptionFilter>();
}
如果您觉的不错,请微信扫码关注 【dotNET 博士】公众号,后续给您带来更精彩的分享