ASP.NET Core フィルターFilters in ASP.NET Core

作成者: Kirk LarkinRick AndersonTom DykstraSteve SmithBy Kirk Larkin, Rick Anderson, Tom Dykstra, and Steve Smith

ASP.NET Core でフィルターを使用すると、要求処理パイプラインの特定のステージの前または後にコードを実行できます。Filters in ASP.NET Core allow code to be run before or after specific stages in the request processing pipeline.

組み込みのフィルターでは次のようなタスクが処理されます。Built-in filters handle tasks such as:

  • 許可 (ユーザーに許可が与えられていないリソースの場合、アクセスを禁止する)。Authorization (preventing access to resources a user isn't authorized for).
  • 応答キャッシュ (要求パイプラインを迂回し、キャッシュされている応答を返す)。Response caching (short-circuiting the request pipeline to return a cached response).

横断的な問題を処理するカスタム フィルターを作成できます。Custom filters can be created to handle cross-cutting concerns. 横断的な問題の例には、エラー処理、キャッシュ、構成、認証、ログなどがあります。Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. フィルターにより、コードの重複が回避されます。Filters avoid duplicating code. たとえば、エラー処理例外フィルターではエラー処理を統合できます。For example, an error handling exception filter could consolidate error handling.

このドキュメントは、Razor Pages、API コントローラー、ビューのあるコントローラーに当てはまります。This document applies to Razor Pages, API controllers, and controllers with views.

サンプルを表示またはダウンロードします (ダウンロード方法)。View or download sample (how to download).

フィルターのしくみHow filters work

ASP.NET Core のアクション呼び出しパイプライン内で実行されるフィルターは、フィルター パイプラインと呼ばれることがあります。Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. フィルター パイプラインは、ASP.NET Core が実行するアクションを選択した後に実行されます。The filter pipeline runs after ASP.NET Core selects the action to execute.

要求は、他のミドルウェア、ルーティング ミドルウェア、アクション選択、ASP.NET Core のアクション呼び出しパイプラインを通じて処理されます。

フィルターの種類Filter types

フィルターの種類はそれぞれ、フィルター パイプラインの異なるステージで実行されます。Each filter type is executed at a different stage in the filter pipeline:

  • 承認フィルターは、最初に実行され、ユーザーが要求に対して承認されているかどうかを判断するために使用されます。Authorization filters run first and are used to determine whether the user is authorized for the request. 承認フィルターでは、要求が承認されていない場合、パイプラインがショートサーキットされます。Authorization filters short-circuit the pipeline if the request is unauthorized.

  • リソース フィルター:Resource filters:

    • 承認後に実行されます。Run after authorization.
    • OnResourceExecuting では、残りのフィルター パイプラインの前にコードを実行できます。OnResourceExecuting can run code before the rest of the filter pipeline. たとえば、OnResourceExecuting では、モデル バインディングの前にコードを実行できます。For example, OnResourceExecuting can run code before model binding.
    • OnResourceExecuted では、残りのパイプラインの完了後にコードを実行できます。OnResourceExecuted can run code after the rest of the pipeline has completed.
  • アクション フィルターは、個々のアクション メソッドが呼び出される直前と直後にコードを実行できます。Action filters can run code immediately before and after an individual action method is called. アクションに渡される引数とアクションから返される結果を操作するために使用できます。They can be used to manipulate the arguments passed into an action and the result returned from the action. アクション フィルターは Razor Pages ではサポートされていませんAction filters are not supported in Razor Pages.

  • 例外フィルターは、応答本文に何かが書き込まれる前に発生する未処理の例外にグローバル ポリシーを適用するために使用されます。Exception filters are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body.

  • 結果フィルターは、個々のアクション結果の実行の直前と直後にコードを実行できます。Result filters can run code immediately before and after the execution of individual action results. アクション メソッドが正常に実行された場合にのみ実行されます。They run only when the action method has executed successfully. ビューまたはフォーマッタ実行を取り囲む必要があるロジックに便利です。They are useful for logic that must surround view or formatter execution.

フィルターの種類がフィルター パイプラインでどのように連携しているかを、次の図に示します。The following diagram shows how filter types interact in the filter pipeline.

要求は、承認フィルター、リソース フィルター、モデル バインド、アクション フィルター、アクションの実行とアクション結果の変換、例外フィルター、結果フィルター、結果の実行を介して処理されます。

実装Implementation

フィルターは、異なるインターフェイス定義を介して、同期と非同期の実装をサポートします。Filters support both synchronous and asynchronous implementations through different interface definitions.

同期フィルターでは、パイプライン ステージの前 (On-Stage-Executing) と後 (On-Stage-Executed) にコードを実行できます。Synchronous filters can run code before (On-Stage-Executing) and after (On-Stage-Executed) their pipeline stage. たとえば、OnActionExecuting はアクション メソッドの呼び出し前に呼び出されます。For example, OnActionExecuting is called before the action method is called. OnActionExecuted は、アクション メソッドが戻った後に呼び出されます。OnActionExecuted is called after the action method returns.

public class MySampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

非同期フィルターにより On-Stage-ExecutionAsync メソッドが定義されます。Asynchronous filters define an On-Stage-ExecutionAsync method:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        // Do something before the action executes.

        // next() calls the action method.
        var resultContext = await next();
        // resultContext.Result is set.
        // Do something after the action executes.
    }
}

上記のコードでは、SampleAsyncActionFilter にアクション メソッドを実行する ActionExecutionDelegate (next) があります。In the preceding code, the SampleAsyncActionFilter has an ActionExecutionDelegate (next) that executes the action method. On-Stage-ExecutionAsync メソッドは、フィルターのパイプライン ステージを実行する FilterType-ExecutionDelegate を受け取ります。Each of the On-Stage-ExecutionAsync methods take a FilterType-ExecutionDelegate that executes the filter's pipeline stage.

複数のフィルター ステージMultiple filter stages

複数のフィルター ステージのためのインターフェイスを 1 つのクラスで実装できます。Interfaces for multiple filter stages can be implemented in a single class. たとえば、ActionFilterAttribute クラスは、IActionFilterIResultFilter、およびそれらの非同期バージョンを実装します。For example, the ActionFilterAttribute class implements IActionFilter, IResultFilter, and their async equivalents.

フィルター インターフェイスの同期と非同期バージョンの両方ではなくいずれかを実装します。Implement either the synchronous or the async version of a filter interface, not both. ランタイムは、最初にフィルターが非同期インターフェイスを実装しているかどうかをチェックして、している場合はそれを呼び出します。The runtime checks first to see if the filter implements the async interface, and if so, it calls that. していない場合は、同期インターフェイスのメソッドを呼び出します。If not, it calls the synchronous interface's method(s). 非同期インターフェイスと同期インターフェイスの両方が 1 つのクラスで実装される場合、非同期メソッドのみが呼び出されます。If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. ActionFilterAttribute などの抽象クラスを使用する場合は、同期メソッドのみをオーバーライドするか、フィルターの種類ごとに非同期メソッドをオーバーライドします。When using abstract classes like ActionFilterAttribute override only the synchronous methods or the async method for each filter type.

組み込みのフィルター属性Built-in filter attributes

ASP.NET Core には、サブクラスを作成したり、カスタマイズしたりできる組み込みの属性ベースのフィルターが含まれます。ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. たとえば、次の結果フィルターは、応答にヘッダーを追加します。For example, the following result filter adds a header to the response:

public class AddHeaderAttribute : ResultFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public AddHeaderAttribute(string name, string value)
    {
        _name = name;
        _value = value;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add( _name, new string[] { _value });
        base.OnResultExecuting(context);
    }
}

上記の例のように、属性によってフィルターは引数を受け取ることができます。Attributes allow filters to accept arguments, as shown in the preceding example. AddHeaderAttribute をコントローラーまたはアクション メソッドに適用し、HTTP ヘッダーの名前と値を指定します。Apply the AddHeaderAttribute to a controller or action method and specify the name and value of the HTTP header:

[AddHeader("Author", "Joe Smith")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

フィルター インターフェイスのいくつかには対応する属性があり、カスタムの実装に基底クラスとして使用できます。Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

フィルター属性:Filter attributes:

フィルターのスコープと実行の順序Filter scopes and order of execution

フィルターは、3 つのスコープのいずれかでパイプラインに追加することができます。A filter can be added to the pipeline at one of three scopes:

  • アクションで属性を使用します。Using an attribute on an action.
  • コントローラーで属性を使用します。Using an attribute on a controller.
  • 次のコードのように、すべてのコントローラーとアクションに対してグローバルに:Globally for all controllers and actions as shown in the following code:
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
            "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

上記のコードでは、MvcOptions.Filters コレクションを利用し、3 つのフィルターがグローバルに追加されます。The preceding code adds three filters globally using the MvcOptions.Filters collection.

実行の既定の順序Default order of execution

パイプラインの特定のステージに対して複数のフィルターがある場合に、スコープがフィルターの実行の既定の順序を決定します。When there are multiple filters for a particular stage of the pipeline, scope determines the default order of filter execution. グローバル フィルターがクラス フィルターを囲み、クラス フィルターがメソッド フィルターを囲みます。Global filters surround class filters, which in turn surround method filters.

フィルターの入れ子の結果として、フィルターの after コードが before コードと逆の順序で実行されます。As a result of filter nesting, the after code of filters runs in the reverse order of the before code. フィルター シーケンス:The filter sequence:

  • グローバル フィルターの before コード。The before code of global filters.
    • コントローラー フィルターの before コード。The before code of controller filters.
      • アクション メソッド フィルターの before コード。The before code of action method filters.
      • アクション メソッド フィルターの after コード。The after code of action method filters.
    • コントローラー フィルターの after コード。The after code of controller filters.
  • グローバル フィルターの after コード。The after code of global filters.

次の例は、同期アクション フィルターに対してフィルター メソッドが呼び出される順序を示しています。The following example that illustrates the order in which filter methods are called for synchronous action filters.

シーケンスSequence フィルターのスコープFilter scope フィルター メソッドFilter method
11 GlobalGlobal OnActionExecuting
22 コントローラーController OnActionExecuting
33 メソッドMethod OnActionExecuting
44 メソッドMethod OnActionExecuted
55 コントローラーController OnActionExecuted
66 GlobalGlobal OnActionExecuted

このシーケンスが示すもの:This sequence shows:

  • メソッド フィルターは、コントローラー フィルター内で入れ子になります。The method filter is nested within the controller filter.
  • コントローラー フィルターは、グローバル フィルター内で入れ子になります。The controller filter is nested within the global filter.

コントローラーと Razor Page のレベル フィルターController and Razor Page level filters

Controller 基底クラスから継承するすべてのコントローラーに、Controller.OnActionExecutingController.OnActionExecutionAsyncController.OnActionExecuted OnActionExecuted メソッドが含まれています。Every controller that inherits from the Controller base class includes Controller.OnActionExecuting, Controller.OnActionExecutionAsync, and Controller.OnActionExecuted OnActionExecuted methods. これらのメソッド:These methods:

  • 特定のアクションに対して実行されるフィルターをラップします。Wrap the filters that run for a given action.
  • OnActionExecuting は、あらゆるアクション フィルターの前に呼び出されます。OnActionExecuting is called before any of the action's filters.
  • OnActionExecuted は、あらゆるアクション フィルターの後に呼び出されます。OnActionExecuted is called after all of the action filters.
  • OnActionExecutionAsync は、あらゆるアクション フィルターの前に呼び出されます。OnActionExecutionAsync is called before any of the action's filters. next の後のフィルターのコードは、アクション メソッドの後に実行されます。Code in the filter after next runs after the action method.

たとえば、ダウンロード サンプルで、MySampleActionFilter は起動中、グローバルに適用されます。For example, in the download sample, MySampleActionFilter is applied globally in startup.

TestController:The TestController:

  • SampleActionFilterAttribute ([SampleActionFilter]) が FilterTest2 アクションに適用されます。Applies the SampleActionFilterAttribute ([SampleActionFilter]) to the FilterTest2 action:
  • OnActionExecutingOnActionExecuted がオーバーライドされます。Overrides OnActionExecuting and OnActionExecuted.
public class TestController : Controller
{
    [SampleActionFilter]
    public IActionResult FilterTest2()
    {
        return Content($"From FilterTest2");
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        base.OnActionExecuted(context);
    }
}

https://localhost:5001/Test/FilterTest2 に移動すると、次のコードが実行されます。Navigating to https://localhost:5001/Test/FilterTest2 runs the following code:

  • TestController.OnActionExecuting
    • MySampleActionFilter.OnActionExecuting
      • SampleActionFilterAttribute.OnActionExecuting
        • TestController.FilterTest2
      • SampleActionFilterAttribute.OnActionExecuted
    • MySampleActionFilter.OnActionExecuted
  • TestController.OnActionExecuted

Razor Pages の場合、「フィルター メソッドをオーバーライドして Razor ページにフィルターを実装する」を参照してください。For Razor Pages, see Implement Razor Page filters by overriding filter methods.

既定の順序のオーバーライドOverriding the default order

IOrderedFilter を実装することで、実行の既定の順序をオーバーライドできます。The default sequence of execution can be overridden by implementing IOrderedFilter. IOrderedFilter により、実行の順序を決定するために、スコープよりも優先される Order プロパティが公開されます。IOrderedFilter exposes the Order property that takes precedence over scope to determine the order of execution. より低い Order 値を持つフィルター:A filter with a lower Order value:

  • より高い Order の値を持つフィルターのそれよりも前に before コードが実行されます。Runs the before code before that of a filter with a higher value of Order.
  • より高い Order の値を持つフィルターのそれよりも後に after コードが実行されます。Runs the after code after that of a filter with a higher Order value.

Order プロパティはコンストラクター パラメーターで設定できます。The Order property can be set with a constructor parameter:

[MyFilter(Name = "Controller Level Attribute", Order=1)]

上記の例にある同じ 3 つのアクション フィルターを検討してください。Consider the same 3 action filters shown in the preceding example. コントローラーとグローバル フィルターの Order プロパティが 1 と 2 にそれぞれ設定される場合、実行順序が逆になります。If the Order property of the controller and global filters is set to 1 and 2 respectively, the order of execution is reversed.

シーケンスSequence フィルターのスコープFilter scope Order プロパティOrder property フィルター メソッドFilter method
11 メソッドMethod 00 OnActionExecuting
22 コントローラーController 11 OnActionExecuting
33 GlobalGlobal 22 OnActionExecuting
44 GlobalGlobal 22 OnActionExecuted
55 コントローラーController 11 OnActionExecuted
66 メソッドMethod 00 OnActionExecuted

フィルターの実行順序を決定するときに、Order プロパティによりスコープがオーバーライドされます。The Order property overrides scope when determining the order in which filters run. 最初に順序でフィルターが並べ替えられ、次に同じ順位の優先度を決めるためにスコープが使用されます。Filters are sorted first by order, then scope is used to break ties. 組み込みのフィルターはすべて IOrderedFilter を実装し、既定の Order 値を 0 に設定します。All of the built-in filters implement IOrderedFilter and set the default Order value to 0. 組み込みのフィルターの場合、Order をゼロ以外の値に設定しない限り、スコープによって順序が決定されます。For built-in filters, scope determines order unless Order is set to a non-zero value.

キャンセルとショートサーキットCancellation and short-circuiting

フィルター メソッドに提供される ResourceExecutingContext パラメーターで Result プロパティを設定することで、フィルター パイプラインをショートサーキットできます。The filter pipeline can be short-circuited by setting the Result property on the ResourceExecutingContext parameter provided to the filter method. たとえば、次のリソース フィルターは、パイプラインの残りの部分が実行されるのを防止します。For instance, the following Resource filter prevents the rest of the pipeline from executing:

public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.Result = new ContentResult()
        {
            Content = "Resource unavailable - header not set."
        };
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

次のコードでは、ShortCircuitingResourceFilterAddHeader の両方のフィルターが SomeResource アクション メソッドをターゲットにしています。In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. ShortCircuitingResourceFilter:The ShortCircuitingResourceFilter:

  • これはリソース フィルターであり、AddHeader はアクション フィルターであるため、最初に実行されます。Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
  • パイプラインの残りの部分は迂回されます。Short-circuits the rest of the pipeline.

そのため、SomeResource アクションの場合、AddHeader フィルターが実行されることはありません。Therefore the AddHeader filter never runs for the SomeResource action. ShortCircuitingResourceFilter が最初に実行された場合は、両方のフィルターがアクション メソッド レベルで適用されると、この動作が同じになります。This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. そのフィルターの種類が原因で、あるいは Order プロパティの明示的な使用により、ShortCircuitingResourceFilter が最初に実行されます。The ShortCircuitingResourceFilter runs first because of its filter type, or by explicit use of Order property.

[AddHeader("Author", "Joe Smith")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

依存関係の挿入Dependency injection

フィルターは種類ごとまたはインスタンスごとに追加できます。Filters can be added by type or by instance. インスタンスが追加される場合、そのインスタンスはすべての要求に対して使用されます。If an instance is added, that instance is used for every request. 種類が追加される場合、それは種類でアクティブ化されます。If a type is added, it's type-activated. 種類でアクティブ化されるフィルターの意味:A type-activated filter means:

  • インスタンスは要求ごとに作成されます。An instance is created for each request.
  • コンストラクターの依存関係は、依存関係の挿入 (DI) によって入力されます。Any constructor dependencies are populated by dependency injection (DI).

属性として実装され、コントローラー クラスまたはアクション メソッドに直接追加されるフィルターは、依存関係の挿入 (DI) によって提供されるコンストラクターの依存関係を持つことはできません。Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). コンストラクターの依存関係は、次の理由から DI によって与えられません。Constructor dependencies cannot be provided by DI because:

  • 属性には、適用される場所で提供される独自のコンストラクター パラメーターが必要です。Attributes must have their constructor parameters supplied where they're applied.
  • これは、属性のしくみの制限です。This is a limitation of how attributes work.

次のフィルターでは、DI から提供されるコンストラクターの依存関係がサポートされます。The following filters support constructor dependencies provided from DI:

上記のフィルターは、コントローラーまたはアクション メソッドに適用できます。The preceding filters can be applied to a controller or action method:

ロガーは DI から利用できます。Loggers are available from DI. ただし、ログ目的でのみフィルターを作成し、使用することは避けてください。However, avoid creating and using filters purely for logging purposes. 組み込みフレームワークのログ機能で通常、ログ記録に必要なものが与えられます。The built-in framework logging typically provides what's needed for logging. フィルターに追加されるログ記録:Logging added to filters:

  • ビジネス ドメインの懸念事項やフィルターに固有の動作に焦点を合わせます。Should focus on business domain concerns or behavior specific to the filter.
  • アクションやその他のフレームワーク イベントはログに記録しないでください。Should not log actions or other framework events. 組み込みフィルターでは、アクションとフレームワーク イベントが記録されます。The built in filters log actions and framework events.

ServiceFilterAttributeServiceFilterAttribute

サービス フィルターの実装の種類は ConfigureServices に登録されています。Service filter implementation types are registered in ConfigureServices. ServiceFilterAttribute は DI からフィルターのインスタンスを取得します。A ServiceFilterAttribute retrieves an instance of the filter from DI.

このコードでは、AddHeaderResultServiceFilter が示されています。The following code shows the AddHeaderResultServiceFilter:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation($"Header added: {headerName}");
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
    }
}

次のコードでは、AddHeaderResultServiceFilter が DI コンテナーに追加されます。In the following code, AddHeaderResultServiceFilter is added to the DI container:

public void ConfigureServices(IServiceCollection services)
{
    // Add service filters.
    services.AddScoped<AddHeaderResultServiceFilter>();
    services.AddScoped<SampleActionFilterAttribute>();

    services.AddMvc(options =>
    {
        options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
            "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

次のコードでは、ServiceFilter 属性により、DI から AddHeaderResultServiceFilter フィルターのインスタンスが取得されます。In the following code, the ServiceFilter attribute retrieves an instance of the AddHeaderResultServiceFilter filter from DI:

[ServiceFilter(typeof(AddHeaderResultServiceFilter))]
public IActionResult Index()
{
    return View();
}

ServiceFilterAttribute.IsReusable:ServiceFilterAttribute.IsReusable:

  • フィルター インスタンスが、それが作成された要求範囲の外で再利用される可能性があることを示唆します。Provides a hint that the filter instance may be reused outside of the request scope it was created within. ASP.NET Core ランタイムで保証されないこと:The ASP.NET Core runtime doesn't guarantee:

    • フィルターのインスタンスが 1 つ作成されます。That a single instance of the filter will be created.
    • フィルターが後の時点で、DI コンテナーから再要求されることはありません。The filter will not be re-requested from the DI container at some later point.
  • シングルトン以外で有効期間があるサービスに依存するフィルターと共に使用しないでください。Should not be used with a filter that depends on services with a lifetime other than singleton.

ServiceFilterAttribute は、IFilterFactory を実装します。ServiceFilterAttribute implements IFilterFactory. IFilterFactory は、IFilterMetadata インスタンスを作成するために CreateInstance メソッドを公開します。IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance により、DI から指定の型が読み込まれます。CreateInstance loads the specified type from DI.

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttributeServiceFilterAttribute と似ていますが、その型は DI コンテナーから直接解決されません。TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. Microsoft.Extensions.DependencyInjection.ObjectFactory を使って型をインスタンス化します。It instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

TypeFilterAttribute 型は DI コンテナーから直接解決されないためです。Because TypeFilterAttribute types aren't resolved directly from the DI container:

  • TypeFilterAttribute を利用して参照される型は、DI コンテナーに登録する必要がありません。Types that are referenced using the TypeFilterAttribute don't need to be registered with the DI container. DI コンテナーによって依存関係が満たされています。They do have their dependencies fulfilled by the DI container.
  • TypeFilterAttribute は必要に応じて、型のコンストラクター引数を受け取ることができます。TypeFilterAttribute can optionally accept constructor arguments for the type.

TypeFilterAttribute を使用する場合、IsReusable を設定すると、フィルター インスタンスが作成された要求の範囲外で再利用できる可能性があることのヒントになります。When using TypeFilterAttribute, setting IsReusable is a hint that the filter instance may be reused outside of the request scope it was created within. ASP.NET Core ランタイムでは、フィルターの 1 インスタンスが作成されるという保証はありません。The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created. シングルトン以外で有効期間があるサービスに依存するフィルターと共に IsReusable を使用しないでください。IsReusable should not be used with a filter that depends on services with a lifetime other than singleton.

次の例は、TypeFilterAttribute を使用して、型に引数を渡す方法を示しています。The following example shows how to pass arguments to a type using TypeFilterAttribute:

[TypeFilter(typeof(LogConstantFilter),
    Arguments = new object[] { "Method 'Hi' called" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}
public class LogConstantFilter : IActionFilter
{
    private readonly string _value;
    private readonly ILogger<LogConstantFilter> _logger;

    public LogConstantFilter(string value, ILogger<LogConstantFilter> logger)
    {
        _logger = logger;
        _value = value;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation(_value);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    { }
}

承認フィルターAuthorization filters

承認フィルター:Authorization filters:

  • フィルター パイプライン内で実行される最初のフィルターです。Are the first filters run in the filter pipeline.
  • アクション メソッドへのアクセスを制御します。Control access to action methods.
  • before メソッドが与えられ、after メソッドは与えられません。Have a before method, but no after method.

カスタム承認フィルターには、カスタム承認フレームワークが必要です。Custom authorization filters require a custom authorization framework. カスタム フィルターを記述するよりも、独自の承認ポリシーを構成するか、カスタム承認ポリシーを記述することを選びます。Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. 組み込み承認フィルター:The built-in authorization filter:

  • 承認システムを呼び出します。Calls the authorization system.
  • 要求は承認されません。Does not authorize requests.

承認フィルター内で例外をスローしませんDo not throw exceptions within authorization filters:

  • 例外は処理されません。The exception will not be handled.
  • 例外フィルターで例外が処理されません。Exception filters will not handle the exception.

承認フィルターで例外が発生した場合、チャレンジ発行を検討してください。Consider issuing a challenge when an exception occurs in an authorization filter.

承認の詳細については、こちらを参照してください。Learn more about Authorization.

リソース フィルターResource filters

リソース フィルター:Resource filters:

リソース フィルターは、ほとんどのパイプラインをショートサーキットする目的で役に立ちます。Resource filters are useful to short-circuit most of the pipeline. たとえば、キャッシュ フィルターにより、キャッシュ ヒットがあるとき、残りのパイプラインを回避できます。For example, a caching filter can avoid the rest of the pipeline on a cache hit.

リソース フィルターの例:Resource filter examples:

アクション フィルターAction filters

重要

アクション フィルターは Razor Pages に適用されませんAction filters do not apply to Razor Pages. Razor Pages では IPageFilterIAsyncPageFilter がサポートされています。Razor Pages supports IPageFilter and IAsyncPageFilter . 詳細については、Razor ページのフィルター メソッドに関するページを参照してください。For more information, see Filter methods for Razor Pages.

アクション フィルター:Action filters:

次のコードは、サンプル アクション フィルターを示しています。The following code shows a sample action filter:

public class MySampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

ActionExecutingContext では次のプロパティが提供されます。The ActionExecutingContext provides the following properties:

  • ActionArguments - アクション メソッドへの入力を読み取ることができます。ActionArguments - enables the inputs to an action method be read.
  • Controller - コントローラー インスタンスを操作できます。Controller - enables manipulating the controller instance.
  • Result - Result を設定すると、アクション メソッドと後続のアクション フィルターの実行がショートサーキットされます。Result - setting Result short-circuits execution of the action method and subsequent action filters.

アクション メソッドで例外をスローする:Throwing an exception in an action method:

  • 後続のフィルターの実行を回避します。Prevents running of subsequent filters.
  • Result の設定とは異なり、結果は成功ではなく、失敗として処理されます。Unlike setting Result, is treated as a failure instead of a successful result.

ActionExecutedContext は、ControllerResult に加え、次のプロパティを提供します。The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled - 別のフィルターによってアクションの実行がショートサーキットされた場合は、true になります。Canceled - True if the action execution was short-circuited by another filter.

  • Exception - アクションまたは前に実行されたアクション フィルターが例外をスローした場合は、null 以外になります。Exception - Non-null if the action or a previously run action filter threw an exception. このプロパティを null に設定する:Setting this property to null:

    • 例外が効果的に処理されます。Effectively handles the exception.
    • Result は、アクション メソッドから返されたかのように実行されます。Result is executed as if it was returned from the action method.

IAsyncActionFilter の場合、ActionExecutionDelegate の呼び出しによって:For an IAsyncActionFilter, a call to the ActionExecutionDelegate:

  • 後続のすべてのアクション フィルターとアクション メソッドが実行されます。Executes any subsequent action filters and the action method.
  • ActionExecutedContext を返します。Returns ActionExecutedContext.

ショートサーキットするには、Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result を結果インスタンスに割り当てます。next (ActionExecutionDelegate) は呼び出さないでください。To short-circuit, assign Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result to a result instance and don't call next (the ActionExecutionDelegate).

このフレームワークからは、サブクラス化できる抽象 ActionFilterAttribute が与えられます。The framework provides an abstract ActionFilterAttribute that can be subclassed.

OnActionExecuting アクション フィルターを次の目的で使用できます。The OnActionExecuting action filter can be used to:

  • モデルの状態を検証します。Validate model state.
  • 状態が有効でない場合は、エラーを返します。Return an error if the state is invalid.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }

OnActionExecuted メソッドは、アクション メソッドの後に実行されます。The OnActionExecuted method runs after the action method:

  • また、Result プロパティを介してアクションの結果を表示したり、操作したりできます。And can see and manipulate the results of the action through the Result property.

  • Canceled は、アクションの実行が別のフィルターによってショートサーキットされた場合、true に設定されます。Canceled is set to true if the action execution was short-circuited by another filter.

  • アクションまたは後続のアクション フィルターが例外をスローした場合、Exception は null 以外の値に設定されます。Exception is set to a non-null value if the action or a subsequent action filter threw an exception. Exception を null に設定すると:Setting Exception to null:

    • 例外が効果的に処理されます。Effectively handles an exception.
    • ActionExecutedContext.Result は、アクション メソッドから通常どおり返されたかのように実行されます。ActionExecutedContext.Result is executed as if it were returned normally from the action method.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }


    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var result = context.Result;
        // Do something with Result.
        if (context.Canceled == true)
        {
            // Action execution was short-circuited by another filter.
        }

        if(context.Exception != null)
        {
            // Exception thrown by action or action filter.
            // Set to null to handle the exception.
            context.Exception = null;
        }
        base.OnActionExecuted(context);
    }
}

例外フィルターException filters

例外フィルター:Exception filters:

次の例外フィルターのサンプルでは、カスタムのエラー ビューを使用して、アプリの開発中に発生する例外に関する詳細を表示します。The following sample exception filter uses a custom error view to display details about exceptions that occur when the app is in development:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

    public CustomExceptionFilterAttribute(
        IHostingEnvironment hostingEnvironment,
        IModelMetadataProvider modelMetadataProvider)
    {
        _hostingEnvironment = hostingEnvironment;
        _modelMetadataProvider = modelMetadataProvider;
    }

    public override void OnException(ExceptionContext context)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            return;
        }
        var result = new ViewResult {ViewName = "CustomError"};
        result.ViewData = new ViewDataDictionary(_modelMetadataProvider,
                                                    context.ModelState);
        result.ViewData.Add("Exception", context.Exception);
        // TODO: Pass additional detailed data via ViewData
        context.Result = result;
    }
}

例外フィルター:Exception filters:

  • before イベントと after イベントが与えられません。Don't have before and after events.
  • OnException または OnExceptionAsync を実装します。Implement OnException or OnExceptionAsync.
  • Razor Page またはコントローラーの作成、モデル バインド、アクション フィルター、またはアクション メソッドで発生する未処理の例外を処理します。Handle unhandled exceptions that occur in Razor Page or controller creation, model binding, action filters, or action methods.
  • リソース フィルター、結果フィルター、または MVC 結果の実行で発生した例外はキャッチしませんDo not catch exceptions that occur in resource filters, result filters, or MVC result execution.

例外を処理するには、ExceptionHandled プロパティを true に設定するか、応答を記述します。To handle an exception, set the ExceptionHandled property to true or write a response. これにより、例外の伝達を停止します。This stops propagation of the exception. 例外フィルターで例外を "成功" に変えることはできません。An exception filter can't turn an exception into a "success". それができるのは、アクション フィルターだけです。Only an action filter can do that.

例外フィルター:Exception filters:

  • アクション内で発生する例外のトラップに適しています。Are good for trapping exceptions that occur within actions.
  • エラー処理ミドルウェアほど柔軟ではありません。Are not as flexible as error handling middleware.

例外処理にはミドルウェアを選択してください。Prefer middleware for exception handling. 呼び出されたアクション メソッドに基づいてエラー処理が異なる状況でのみ例外フィルターを使用します。Use exception filters only where error handling differs based on which action method is called. たとえば、アプリには、API エンドポイントとビュー/HTML の両方に対するアクション メソッドがある場合があります。For example, an app might have action methods for both API endpoints and for views/HTML. API エンドポイントは、JSON としてのエラー情報を返す可能性がある一方で、ビュー ベースのアクションがエラー ページを HTML として返す可能性があります。The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

結果フィルターResult filters

結果フィルター:Result filters:

IResultFilter および IAsyncResultFilterIResultFilter and IAsyncResultFilter

次は、HTTP ヘッダーを追加する結果フィルターのコードです。The following code shows a result filter that adds an HTTP header:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation($"Header added: {headerName}");
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
    }
}

実行されている結果の種類は、アクションに依存します。The kind of result being executed depends on the action. ビューを返すアクションには、実行されている ViewResult の一部として、すべての razor 処理が含まれます。An action returning a view would include all razor processing as part of the ViewResult being executed. API メソッドは、結果の実行の一部としていくつかのシリアル化を実行できます。An API method might perform some serialization as part of the execution of the result. アクション結果に関する詳細は、こちらを参照してください。Learn more about action results

結果フィルターは、アクションまたはアクション フィルターがアクションの結果を生成するときに、成功した結果に対してのみ実行されます。Result filters are only executed for successful results - when the action or action filters produce an action result. 例外フィルターが例外を処理するときには、結果フィルターは実行されません。Result filters are not executed when exception filters handle an exception.

Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting メソッドは、Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Canceltrue に設定することで、アクションの結果と後続の結果フィルターの実行をショートサーキットできます。The Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting method can short-circuit execution of the action result and subsequent result filters by setting Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel to true. ショートサーキットする場合は、空の応答が生成されないように応答オブジェクトに記述します。Write to the response object when short-circuiting to avoid generating an empty response. IResultFilter.OnResultExecuting で例外をスローすることで:Throwing an exception in IResultFilter.OnResultExecuting will:

  • アクション結果と後続フィルターの実行が回避されます。Prevent execution of the action result and subsequent filters.
  • 結果は成功ではなく、失敗として処理されます。Be treated as a failure instead of a successful result.

Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted メソッドが実行されると:When the Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted method runs:

  • 応答はおそらくクライアントに送信されており、変更できません。The response has likely been sent to the client and cannot be changed.
  • 例外がスローされた場合、応答本文は送信されていません。If an exception was thrown, the response body is not sent.

別のフィルターによってアクションの結果の実行がショートサーキットされた場合、ResultExecutedContext.Canceledtrue に設定されます。ResultExecutedContext.Canceled is set to true if the action result execution was short-circuited by another filter.

アクションの結果または後続の結果フィルターが例外をスローした場合、ResultExecutedContext.Exception は null 以外の値に設定されます。ResultExecutedContext.Exception is set to a non-null value if the action result or a subsequent result filter threw an exception. Exception を null に設定すると、例外を効果的に処理でき、パイプラインの後方で ASP.NET Core によって例外が再スローされることを防げます。Setting Exception to null effectively handles an exception and prevents the exception from being rethrown by ASP.NET Core later in the pipeline. 結果フィルターの例外を処理するとき、応答にデータを書き込む目的で信頼できる方法はありません。There is no reliable way to write data to a response when handling an exception in a result filter. アクションの結果により例外がスローされるとき、ヘッダーがクライアントにフラッシュされている場合、エラー コードを送信する目的で信頼できるメカニズムはありません。If the headers have been flushed to the client when an action result throws an exception, there's no reliable mechanism to send a failure code.

IAsyncResultFilter の場合、ResultExecutionDelegateawait next を呼び出すと、後続のすべての結果フィルターとアクションの結果が実行されます。For an IAsyncResultFilter, a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. ショートサーキットするには、ResultExecutingContext.Canceltrue に設定し、ResultExecutionDelegate を呼び出しません。To short-circuit, set ResultExecutingContext.Cancel to true and don't call the ResultExecutionDelegate:

public class MyAsyncResponseFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context,
                                             ResultExecutionDelegate next)
    {
        if (!(context.Result is EmptyResult))
        {
            await next();
        }
        else
        {
            context.Cancel = true;
        }

    }
}

このフレームワークからは、サブクラス化できる抽象 ResultFilterAttribute が与えられます。The framework provides an abstract ResultFilterAttribute that can be subclassed. 前に示した AddHeaderAttribute クラスは、結果フィルター属性の一例です。The AddHeaderAttribute class shown previously is an example of a result filter attribute.

IAlwaysRunResultFilter および IAsyncAlwaysRunResultFilterIAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter

IAlwaysRunResultFilter および IAsyncAlwaysRunResultFilter インターフェイスでは、すべてのアクションの結果に対して実行される IResultFilter の実装が宣言されます。The IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter interfaces declare an IResultFilter implementation that runs for all action results. 次の場合を除き、フィルターはすべてのアクションの結果に適用されます。The filter is applied to all action results unless:

  • IExceptionFilter または IAuthorizationFilter が適用され、応答がショートサーキットされます。An IExceptionFilter or IAuthorizationFilter applies and short-circuits the response.
  • アクションの結果を生成することで、例外フィルターによって例外が処理されます。An exception filter handles an exception by producing an action result.

IExceptionFilterIAuthorizationFilter 以外のフィルターによって IAlwaysRunResultFilterIAsyncAlwaysRunResultFilter がショートサーキットされることはありません。Filters other than IExceptionFilter and IAuthorizationFilter don't short-circuit IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter.

たとえば、次のフィルターは常に実行され、コンテンツ ネゴシエーションが失敗した場合に "422 処理不可エンティティ" 状態コードを使ってアクションの結果 (ObjectResult) を設定します。For example, the following filter always runs and sets an action result (ObjectResult) with a 422 Unprocessable Entity status code when content negotiation fails:

public class UnprocessableResultFilter : Attribute, IAlwaysRunResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is StatusCodeResult statusCodeResult &&
            statusCodeResult.StatusCode == 415)
        {
            context.Result = new ObjectResult("Can't process this!")
            {
                StatusCode = 422,
            };
        }
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
    }
}

IFilterFactoryIFilterFactory

IFilterFactory は、IFilterMetadata を実装します。IFilterFactory implements IFilterMetadata. そのため、IFilterFactory インスタンスはフィルター パイプライン内の任意の場所で IFilterMetadata インスタンスとして使用できます。Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. ランタイムでは、フィルターを呼び出す準備をする際、IFilterFactory へのキャストが試行されます。When the runtime prepares to invoke the filter, it attempts to cast it to an IFilterFactory. そのキャストが成功した場合、呼び出される IFilterMetadata インスタンスを作成するために CreateInstance メソッドが呼び出されます。If that cast succeeds, the CreateInstance method is called to create the IFilterMetadata instance that is invoked. これにより、アプリの起動時に正確なフィルター パイプラインを明示的に設定する必要がないため、柔軟なデザインが可能になります。This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.

フィルターを作成するための別の方法として、カスタムの属性の実装で IFilterFactory を実装できます。IFilterFactory can be implemented using custom attribute implementations as another approach to creating filters:

public class AddHeaderWithFactoryAttribute : Attribute, IFilterFactory
{
    // Implement IFilterFactory
    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        return new InternalAddHeaderFilter();
    }

    private class InternalAddHeaderFilter : IResultFilter
    {
        public void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(
                "Internal", new string[] { "My header" });
        }

        public void OnResultExecuted(ResultExecutedContext context)
        {
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

ダウンロード サンプルを実行することで、前のコードをテストできます。The preceding code can be tested by running the download sample:

  • F12 開発者ツールを呼び出します。Invoke the F12 developer tools.
  • https://localhost:5001/Sample/HeaderWithFactory に移動します。Navigate to https://localhost:5001/Sample/HeaderWithFactory

F12 開発者ツールでは、サンプル コードによって追加された次の応答ヘッダーが表示されます。The F12 developer tools display the following response headers added by the sample code:

  • author: Joe Smithauthor: Joe Smith
  • globaladdheader: Result filter added to MvcOptions.Filtersglobaladdheader: Result filter added to MvcOptions.Filters
  • internal: My headerinternal: My header

上記のコードでは、internal: My header という応答ヘッダーが作成されます。The preceding code creates the internal: My header response header.

属性に実装された IFilterFactoryIFilterFactory implemented on an attribute

IFilterFactory を実装するフィルターは次のようなフィルターに便利です。Filters that implement IFilterFactory are useful for filters that:

  • パラメーターの引き渡しを必要としません。Don't require passing parameters.
  • DI で満たす必要があるコンストラクター依存関係があります。Have constructor dependencies that need to be filled by DI.

TypeFilterAttribute は、IFilterFactory を実装します。TypeFilterAttribute implements IFilterFactory. IFilterFactory は、IFilterMetadata インスタンスを作成するために CreateInstance メソッドを公開します。IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. CreateInstance により、サービス コンテナー (DI) から指定の型が読み込まれます。CreateInstance loads the specified type from the services container (DI).

public class SampleActionFilterAttribute : TypeFilterAttribute
{
    public SampleActionFilterAttribute():base(typeof(SampleActionFilterImpl))
    {
    }

    private class SampleActionFilterImpl : IActionFilter
    {
        private readonly ILogger _logger;
        public SampleActionFilterImpl(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            _logger.LogInformation("Business action starting...");
            // perform some business logic work

        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // perform some business logic work
            _logger.LogInformation("Business action completed.");
        }
    }
}

次のコードでは、[SampleActionFilter] を適用する 3 つの手法を確認できます。The following code shows three approaches to applying the [SampleActionFilter]:

[SampleActionFilter]
public IActionResult FilterTest()
{
    return Content($"From FilterTest");
}

[TypeFilter(typeof(SampleActionFilterAttribute))]
public IActionResult TypeFilterTest()
{
    return Content($"From ServiceFilterTest");
}

// ServiceFilter must be registered in ConfigureServices or
// System.InvalidOperationException: No service for type '<filter>' has been registered.
// Is thrown.
[ServiceFilter(typeof(SampleActionFilterAttribute))]
public IActionResult ServiceFilterTest()
{
    return Content($"From ServiceFilterTest");
}

上記のコードでは、SampleActionFilter を適用する方法としては、[SampleActionFilter] でメソッドを装飾する方法が推奨されます。In the preceding code, decorating the method with [SampleActionFilter] is the preferred approach to applying the SampleActionFilter.

フィルター パイプラインでのミドルウェアの使用Using middleware in the filter pipeline

リソース フィルターは、パイプラインの後方で登場するすべての実行を囲む点で、ミドルウェアのように機能します。Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. ただし、フィルターは ASP.NET Core ランタイムの一部である点がミドルウェアとは異なります。つまり、フィルターには ASP.NET Core コンテキストとコンストラクトへのアクセスがあります。But filters differ from middleware in that they're part of the ASP.NET Core runtime, which means that they have access to ASP.NET Core context and constructs.

ミドルウェアをフィルターとして使用するには、フィルター パイプラインに挿入するミドルウェアを指定する Configure メソッドを使用して型を作成します。To use middleware as a filter, create a type with a Configure method that specifies the middleware to inject into the filter pipeline. ローカリゼーション ミドルウェアを使用して要求の現在のカルチャを確立する例を次に示します。The following example uses the localization middleware to establish the current culture for a request:

public class LocalizationPipeline
{
    public void Configure(IApplicationBuilder applicationBuilder)
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("fr")
        };

        var options = new RequestLocalizationOptions
        {

            DefaultRequestCulture = new RequestCulture(culture: "en-US", 
                                                     uiCulture: "en-US"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };
        options.RequestCultureProviders = new[] 
            { new RouteDataRequestCultureProvider() { Options = options } };

        applicationBuilder.UseRequestLocalization(options);
    }
}

MiddlewareFilterAttribute を使用し、ミドルウェアを実行します。Use the MiddlewareFilterAttribute to run the middleware:

[Route("{culture}/[controller]/[action]")]
[MiddlewareFilter(typeof(LocalizationPipeline))]
public IActionResult CultureFromRouteData()
{
    return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},"
        + $"CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
}

ミドルウェア フィルターは、フィルター パイプラインのリソース フィルターと同じステージ (モデル バインドの前、残りのパイプラインの後) で実行されます。Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.

次の操作Next actions