ASP.NET WebAPI 13 Filter

6000 ワード

Filter(フィルタ)はAOP(側面プログラミング向け)に基づく設計であり,Actionrの実行は横断注入の目的を達成するために追加の論理を注入する役割を果たす.
 

IFilter


WebAPIでは、IFIlterインタフェースが実装されています.IFIlterインタフェースには、同じターゲットオブジェクトに適用できるかどうかを示す読み取り専用プロパティAllowMultipleが1つしかありません.
 
 
public interface IFilter

{ 

bool AllowMultiple { get; } 

 }

 
 
 
 

FilterInfo


HttpActionDescriptorとHttpControllerDescriptorにもActionで使用したFilterが格納されています.ただし、IFIlter形式で直接保存するのではなく、FilterInfo(System.Web.Http.Filters)で保存します.
 
public sealed class FilterInfo

 {

public FilterInfo(IFilter instance, FilterScope scope); 

public IFilter Instance { get; } 

public FilterScope Scope { get; } 

 }

 
 
 
FilterInfoには2つのプロパティがあります.Instance,Scopeです.ここでInstanceはIFIlterオブジェクトです.実際のFilter運用では、同じFilterに対して呼び出されるのは同じFilterオブジェクトであるため、同時の状況に注意する必要があります.  
 
 
 

FilterScope


 
FilterInfoクラスのScopeプロパティでは、Filterのドメインを表します.WebAPIでFilterにはGlobal,Controller,Actionの3つのドメインがある.
 
public enum FilterScope

 { 

 Global = 0, 

 Controller = 10, 

 Action = 20, 

 }

 
 
 
Controllerの場合、ActionのFilter追加はすべてプロパティ(Attribute)方式を採用します.グローバルFilterについては、HttpConfigurationに追加されたFilterです.
 
 
 

FilterProvider


WebAPIは、IFIlterProvider(System.Web.Http.Filters)を使用して、異なるドメインでのFilterを提供します.
 
public interface IFilterProvider

{

IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor); 

 }

 
 
 
WebAPIにおいてもFilterProviderは「標準化コンポーネント」であるがmultiとして注入する.WebAPIのIFIlterには2つのデフォルト実装があります.ConfigurationFilterProvider、ActionDescriptorFilterProviderです.名前から、前者はグローバルFilterを提供し、後者はController、Actionを提供するFilterであることがわかります.
 
 
 
 

5種類のFilter


WebAPIは5種類のFilterを定義してくれた.それぞれ次のようになります.
AuthenticationFilter:認証を要求するために使用されます(IAuthenticationFilter).
AuthorizationFilter:承認を要求するために使用されます(IAuthorizationFilter).
ActionFilter:ActionFilter:登録されたアクションは、Actionの実行前後に呼び出されます(IActionFilter).
ExceptionFilter:ターゲットActionが例外を放出したときに呼び出されます(IExceptionFilter).
OverrideFilter:現在のドメインをブロックする前のFilter(IOverrideFilter).
 
本文は後の3種類のFilterに重点を置いて、前の2種類に対して、後でフォローします.次の3つのタイプのFilterのデフォルト実装は、ActionFilterAttribute、ExceptionFilterAttribute、O v e r r i d e ActionFilterAttributeです.次のようになります.
 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 

public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IFilter

 {

protected ActionFilterAttribute(); 

public virtual void OnActionExecuted(HttpActionExecutedContext actionExecutedContext); 

public virtual Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken); 

public virtual void OnActionExecuting(HttpActionContext actionContext); 

public virtual Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken); 

 }

 
 
 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 

public abstract class ExceptionFilterAttribute : FilterAttribute, IExceptionFilter, IFilter

 { 

protected ExceptionFilterAttribute(); 

public virtual void OnException(HttpActionExecutedContext actionExecutedContext); 

public virtual Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken); 

 }

 
 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 

public sealed class OverrideActionFiltersAttribute : Attribute, IOverrideFilter, IFilter

 { 

public OverrideActionFiltersAttribute(); 

public Type FiltersToOverride { get; } 

 }

 
 
 
 
 
 

ユニーク性


Filterには3つのドメインがあるので,特性表示を用いてFilterを注入すると,必ず同じActionに複数の同じFilterを注入する可能性がある.明らかに使用中にこのような状況が発生することは一般的に許されない.WebAPIでは、Filterの一意性を保証するための適切なポリシーが提供されています.すなわち、FilterAttributeにAttributeUsageプロパティを追加し、AllowMultipleをfalseに設定.
もちろん、この設定の後、3つのドメインに同じFilterを追加することができます.そうすると、WebAPIは私たちのためにFilterをフィルタして呼び出します.フィルタルールは次のとおりです.
Action>Controller>Global
つまりFilterScopeの値が大きいほど優先度が高くなります.
 
 

ActionFilter


ActionFilterAttributeは4つの虚メソッドを提供している:OnActionExecuted,OnActionExecutedAsync,OnActionExecuting,OnActionExecutingAsync実は2つの非同期メソッドは2つの同期メソッドのパッケージにすぎないので、一般的には2つの同期メソッドのみを書き換える.
 
 
実行順序でActionFilterのルールは次のとおりです.

  • 異なるドメイン:Global>ControllerAction

  • 同じドメイン:注入順に実行

  •  
    OnActionExecutionの実行中にactionContext.Responseが値を割り当てると、Filterパイプは戻り処理され、後続の操作は行われません.
     
     

    ExceptionFilter


    ActionとActionFilterパイプ全体の実行中に異常が放出された場合、
     

  • ExpceptionFilterの実行順序はActionFilterと正反対です

  • ExceptionFilterパイピング処理は、ActionFilterパイピング全体から放出される異常であり、単なるAction放出の異常ではない

  • ExceptionFilterパイプラインで例外が放出された場合、ExceptionFilterは実行されません.

  •  
     

    OverrideFilter


    1つのActionのすべてのFilterはGlobal,Controller,Actionの3つのドメインの下のFilterの合計ですが,ある時は上位ドメインのFilterがほしいと思っているときにOverrideFilterを使う必要があります.WebAPIのO v e r rideActionFiltersAttributeはIActionFilterのみをマスクし、他のFilterはマスクしません.
     

    ソースコード


     
    Github: https://github.com/BarlowDu/WebAPI (API_13)