asp.Netのcoreシリーズの経験総括:私たちはどのように実戦の中でActionFilterを利用します

7973 ワード

asp.Netのcoreシリーズ経験まとめ:ActionFilterを実戦でどのように利用するか
0.前書き前編では、UnitOfWorkを作成し、ActionFilter設定で有効にする方法について説明しました.この記事では、ActionFilterとActionFilterの使い方を簡単に紹介します.
  • ActionFilter概要ActionFilterのフルネームはActionFilterAttributeです.マイクロソフトの命名規範に基づいて、これは特性クラスであることがわかります.声明を見てください.
  • [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple=true,Inherited=true)]public abstract class ActionFilterAttribute:Attribute,IActionFilter,IbilterMetata,IAsyncActionFilter,IAsyncActionFilter,IAsyncResultFilter,IOrderedFilter,IresultFilterクラスクラスとはクラスとメソッドに表記できる特性クラスであり、複数のタグを許可し、後にサブクラスクラスのサブクラスのサブクラスのサブクラスを表記し、後にサブクラスのサブクラスのサブクラスのサブクラスのサブクラスのラベルを表記し、後にサブクラスのサブクラスのサブクラスのサブクラスのサブクラス親のプロパティが継承されます.そして、このクラスは抽象的なクラスなので、ActionFilterAttributeを継承することで自分のActionFilterを作成することができます.
    1.1 ActionFilterの4つのメソッド1つのActionFilterにとって最も重要なのは、その4つのメソッドです.
    public virtual void OnActionExecuted(ActionExecutedContext context);
    public virtual void OnActionExecuting(ActionExecutingContext context);
    
    public virtual void OnResultExecuted(ResultExecutedContext context);
    public virtual void OnResultExecuting(ResultExecutingContext context);

    上図は、この4つの方法が1回のリクエストで実行される順序です.1回のリクエストが実際に実行される前に、このリクエストをブロックするには、OnActionExecutingを使用します.
    どうして単独でこれを言うのですか.この方法はオーディション率が高いため,この方法を用いてリクエストフィルタリングを行うことが多い.
    1.2 ActionFilterで何ができるか簡単に紹介します.4つの方法のうち4つのコンテキストタイプを見て、利用できる方法を見てみましょう.
    1.2.1 ActionExecutingContext
    これは、アクションが実行されていないことを示すアクション実行前のコンテキストですが、コントローラのインスタンスが取得されました.
    public class ActionExecutingContext : FilterContext
    {
        public virtual IDictionary ActionArguments { get; }
        public virtual object Controller { get; }
        public virtual IActionResult Result { get; set; }
    }
    

    ActionExecutingContextはFilterContextから継承されています.親には関心を持たず、独自の属性だけを見てみましょう.
    ActionArgumentsはActionを表すパラメータのリストである、この中にはユーザから要求パラメータや他の中間処理プログラムから追加された各種パラメータControllerがその要求を実行することを示すコントローラが入っている.Netcoreはコントローラに対する制限が小さいため,コントローラのどのタイプでも可能であるため,ここではobjectをコントローラタイプResultの実行結果として用いるが,通常,ここでこの属性の値を取得することは意味がない.しかし、このプロパティの値を変更することで、1.2.2 ActionExecutedContextリクエストをブロックできます.
    ActionExecutedContextは、Actionの実行が完了したコンテキストを表し、Actionが完了した場合、Actionの実行結果を取得できます.
    public class ActionExecutedContext : FilterContext
    {
        public virtual bool Canceled { get; set; }
        public virtual object Controller { get; }
        public virtual Exception Exception { get; set; }
        public virtual ExceptionDispatchInfo ExceptionDispatchInfo { get; set; }
        public virtual bool ExceptionHandled { get; set; }
        public virtual IActionResult Result { get; set; }
    }

    同様に、FilterContextから継承され、しばらく無視されます.
    Canceledは、ショートコントローラの処理要求が設定されているか否かを示すコントローラExceptionの実行中に異常が発生したか否かを示し、異常があれば値があり、そうでなければNull ExceptionHandled異常が処理されたか否かResultここでResultを修正して実行されたActionResultをマスクしないが、対応する実装1.2.3 ResultExecutingContextをユーザに隠すことができる
    これはResultレンダリングの前に実行されたコンテキストです.アクションが完了し、Resultをレンダリングする準備ができています.
    public class ResultExecutingContext : FilterContext
    {
        public virtual bool Cancel { get; set; }
        public virtual object Controller { get; }
        public virtual IActionResult Result { get; set; }
    }

    Cancel現在の結果実行および後続フィルタの実行をキャンセルControllerコントローラResult処理結果1.2.4 ResultExecutedContext
    Resultの実行が完了し、実行結果コンテキストを取得しました.
    public class ResultExecutedContext : FilterContext
    {
        public virtual bool Canceled { get; set; }
        public virtual object Controller { get; }
        public virtual Exception Exception { get; set; }
        public virtual ExceptionDispatchInfo ExceptionDispatchInfo { get; set; }
        public virtual bool ExceptionHandled { get; set; }
        public virtual IActionResult Result { get; }
    }

    このクラスはActionExecutedContextと似ているので、紹介しません.
    1.2.5 FilterContext
    上記の4つのコンテキストはFilterContextから継承されています.では、FilterContextにどのようなプロパティまたはメソッドがあるかを見てみましょう.
    public abstract class FilterContext : ActionContext
    {
        public virtual IList Filters { get; }
        public TMetadata FindEffectivePolicy() where TMetadata : IFilterMetadata;
    }

    FilterContextが別のActionContextのクラスを継承していることがわかります.仲間たちはこのクラスに対して一定の概念を持つべきで、このクラスはActionのコンテキストクラスです.1つのActionのライフサイクルに完全に存在するため、ActionContextを介してActionレベルのデータ転送が可能になる場合があります(推奨されません).
    では、ActionContextに何があるか振り返ってみましょう.
    public class ActionContext
    {
        public ActionDescriptor ActionDescriptor { get; set; }
        public HttpContext HttpContext { get; set; }
        public ModelStateDictionary ModelState { get; }
        public RouteData RouteData { get; set; }
    }

    ActionDescriptorが実行するAction記述情報は、Actionの表示名、いくつかのパラメータなどを含むが、具体的に使用する場合、HttpContextはこの属性を通じて今回要求されたRequestとResponseオブジェクトModelStateモデルの検証情報を取得することができると詳細に説明し、この部分は後でRouteDataルーティング情報、asp.Netcoreが要求を処理する際に解析したルーティング情報は,プログラムで修正したルーティング情報を含む.
  • ActionFilterを使用した『【asp.net coreシリーズ】9実戦のUnitOfWorkおよびカスタムコード生成』前編では、ActionFilterが通常の特性クラスと一致していることを説明しており、コントローラを表示してこのActionFilterを有効にすることができます.

  • 多くの場合、1つのActionFilterは1つのコントローラに限定されるのではなく、複数のコントローラに適用されるからです.したがって、この場合、基本コントローラを設定し、このコントローラに寸法を付けて、サブクラスにこのコントローラを継承させます.このようにして、1回の宣言の複数回の使用を実現します.
    もちろんaspではNetcoreにはActionFilterを使用する別の方法が追加する、Setup.cs中
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }

    デフォルトでは、パラメータを設定してグローバルアプリケーションのFilterを追加できます.たとえば、前回の記事で作成した
    UnitOfWorkFilterAttribute:
    
    services.AddControllersWithViews(options=>
    {
        options.Filters.Add();
    });

    これにより、グローバルActionFilterを有効にすることができます.aspを使用する必要がある場合.Netcoreのデフォルト依存注入はAddServiceを使用して構成できます.(注入に依存する内容は後述).
  • ツールクラス生成は、
  • に続きます.
    public static void CreateEntityTypeConfig(Type type)
    {
        var targetNamespace = type.Namespace.Replace("Data.Models", "");
        if (targetNamespace.StartsWith("."))
        {
            targetNamespace = targetNamespace.Remove(0);
        }
        var targetDir = Path.Combine(new[] { CurrentDirect, "Domain.Implements", "EntityConfigures" }.Concat(
            targetNamespace.Split('.')).ToArray());
    
        if (!Directory.Exists(targetDir))
        {
            Directory.CreateDirectory(targetDir);
        }
        var baseName = type.Name.Replace("Entity", "");
        if (!string.IsNullOrEmpty(targetNamespace))
        {
            targetNamespace = $".{targetNamespace}";
        }
    
        var file = $"using {type.Namespace};" +
            $"\r
    using Microsoft.EntityFrameworkCore;" + $"\r
    using Microsoft.EntityFrameworkCore.Metadata.Builders;" + $"\r
    namespace Domain.Implements.EntityConfigures{targetNamespace}" + "\r
    {" + $"\r
    \tpublic class {baseName}Config : IEntityTypeConfiguration" + "\r
    \t{" + "\r
    \t\tpublic void Configure(EntityTypeBuilder builder)" + "\r
    \t\t{" + $"\r
    \t\t\tbuilder.ToTable(\"{baseName}\");" + $"\r
    \t\t\tbuilder.HasKey(p => p.Id);" + "\r
    \t\t}\r
    \t}\r
    }"; File.WriteAllText(Path.Combine(targetDir, $"{baseName}Config.cs"), file); }

    ツールクラスは本質的にファイルの書き込み方法であり、それ自体は難しくありません.
    しかし、ここには小さな問題があります.呼び出すたびに元のファイルを上書きします.また、この中には最適化できる場所がたくさんあります.仲間たちは自分で最適化して、コードをもっときれいにすることができます.
    4これまでに、実戦シリーズもいくつかありましたが、ソースコードを提供してもらえますか?もちろん、できますよ.しかし、今ではありません.謎を残しておきます.メインフレームワークの機能が完了すると、私は仲間たちにコードを送ります.
    実はまだ完全ではないので、仲間たちに開放しても意味がありません.もちろん、一緒に叩いても、実現できますよ.キーのコードはすべてあります.
    参考資料:https://www.cnblogs.com/c7jie/p/13155592.htmlhttps://blog.csdn.net/weixin_30656145/article/details/98941844http://www.chnmoney.com/tongdaxingongshi/88389.htmlhttps://www.cnblogs.com/c7jie/p/13128862.htmlhttps://blog.csdn.net/ma524654165/article/details/77586615