필터Filters

Tom DykstraSteve SmithBy Tom Dykstra and Steve Smith

필터 ASP.NET Core MVC에서 앞 이나 뒤 요청 처리 파이프라인의 특정 단계 코드를 실행할 수 있도록 합니다.Filters in ASP.NET Core MVC allow you to run code before or after certain stages in the request processing pipeline.

모든 요청이 HTTPS 및 응답 (캐시 된 응답을 반환 하는 요청 파이프라인 단락 (short-circuiting)) 캐싱 사용 하는 확인 하는 권한 부여 (리소스에 대 한 권한이 없는 사용자에 대 한 액세스를 방지), 같은 기본 제공 필터 핸들 작업입니다.Built-in filters handle tasks such as authorization (preventing access to resources a user isn't authorized for), ensuring that all requests use HTTPS, and response caching (short-circuiting the request pipeline to return a cached response).

응용 프로그램에 대 한 일반적인 문제를 처리 하는 사용자 지정 필터를 만들 수 있습니다.You can create custom filters to handle cross-cutting concerns for your application. 작업에서 코드 중복 되지 않도록 하려면 언제 든 지 필터는 것이 좋습니다.Anytime you want to avoid duplicating code across actions, filters are the solution. 예를 들어 오류 처리 코드에 예외 필터를 통합할 수 있습니다.For example, you can consolidate error handling code in a exception filter.

보기 또는 GitHub에서 샘플을 다운로드합니다.View or download sample from GitHub.

필터는 어떻게 작동 하나요?How do filters work?

내에서 실행 되는 필터는 MVC 동작 호출 파이프라인때로는 라고 하는 필터 파이프라인합니다.Filters run within the MVC action invocation pipeline, sometimes referred to as the filter pipeline. 필터 파이프라인 실행할 작업을 선택 하는 MVC 후 실행 됩니다.The filter pipeline runs after MVC selects the action to execute.

다른 미들웨어, 라우팅 미들웨어, 작업 선택 및 MVC 동작 호출 파이프라인을 통해 요청이 처리 됩니다.

필터 형식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 current user is authorized for the current request. 있습니다 수 단락 (short-circuit) 파이프라인 경우 요청이 인증 되지 않습니다.They can short-circuit the pipeline if a request is unauthorized.

  • 리소스 필터 에 권한 부여 요청을 처리 됩니다.Resource filters are the first to handle a request after authorization. 필터 파이프라인 및 파이프라인의 나머지 부분에서 완료 된 후 나머지 앞에 코드를 실행할 수 있습니다.They can run code before the rest of the filter pipeline, and after the rest of the pipeline has completed. 캐싱을 구현 또는 그렇지 않은 경우 성능상의 이유로 필터 파이프라인 단락 (short-circuit)에 유용 합니다.They're useful to implement caching or otherwise short-circuit the filter pipeline for performance reasons. 모델 바인딩 전에 실행 하기 때문에 바인딩하는 모델에 영향을 줍니다 필요한 모든 항목에 대 한 유용 합니다.Since they run before model binding, they're useful for anything that needs to influence model binding.

  • 작업 필터 하기 직전 및 개별 작업 메서드가 호출 된 후에 코드를 실행할 수 있습니다.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.

  • 예외 필터 아무 것도 응답 본문에 쓰여지기 전에 발생 하는 처리 되지 않은 예외에 전역 정책을 적용 하는 데 사용 됩니다.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 and are useful for logic that must surround view or formatter execution.

다음 다이어그램에서는 이러한 종류의 필터는 필터 파이프라인에서 상호 작용 하는 방법을 보여 줍니다.The following diagram shows how these filter types interact in the filter pipeline.

요청 권한 부여 필터, 리소스 필터, 모델 바인딩, 동작 필터, 액션 실행 및 작업 결과 변환, 예외 필터, 결과 필터 및 결과 실행을 통해 처리 됩니다.

구현Implementation

필터에는 다른 인터페이스 정의 통해 동기 및 비동기 구현을 지원 합니다.Filters support both synchronous and asynchronous implementations through different interface definitions. 수행 해야 하는 작업의 종류에 따라 동기화 또는 비동기 variant를 선택 합니다.Choose either the sync or async variant depending on the kind of task you need to perform.

전과 후에 해당 파이프라인 단계 정의 둘 다 동기 필터를 실행할 수 있는 코드단계Executing 및단계메서드를 실행 합니다.Synchronous filters that can run code both before and after their pipeline stage define OnStageExecuting and OnStageExecuted methods. 예를 들어 OnActionExecuting 동작 메서드를 호출 하기 전에 라고 및 OnActionExecuted 동작 메서드에서 반환 된 후 호출 됩니다.For example, OnActionExecuting is called before the action method is called, and OnActionExecuted is called after the action method returns.

using FiltersSample.Helper;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FiltersSample.Filters
{
    #region snippet_ActionFilter
    public class SampleActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // do something before the action executes
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // do something after the action executes
        }
    }
    #endregion
}

비동기 필터에는 단일 정의단계ExecutionAsync 메서드.Asynchronous filters define a single OnStageExecutionAsync method. 이 메서드는 FilterType필터의 파이프라인 단계를 실행 하는 ExecutionDelegate 대리자입니다.This method takes a FilterTypeExecutionDelegate delegate which executes the filter's pipeline stage. 예를 들어 ActionExecutionDelegate 호출 동작 메서드를 실행할 수 있습니다 코드 전과 후 프로시저를 호출 합니다.For example, ActionExecutionDelegate calls the action method, and you can execute code before and after you call it.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FiltersSample.Filters
{
    public class SampleAsyncActionFilter : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(
            ActionExecutingContext context,
            ActionExecutionDelegate next)
        {
            // do something before the action executes
            var resultContext = await next();
            // do something after the action executes; resultContext.Result will be set
        }
    }
}

단일 클래스에 여러 필터 단계에 대 한 인터페이스를 구현할 수 있습니다.You can implement interfaces for multiple filter stages in a single class. 예를 들어는 ActionFilterAttribute 둘 다 추상 클래스 구현 IActionFilterIResultFilter, 비동기 상응 뿐만 아니라 합니다.For example, the ActionFilterAttribute abstract class implements both IActionFilter and IResultFilter, as well as their async equivalents.

참고

구현 어느 동기 또는 둘 다 필터 인터페이스의 비동기 버전입니다.Implement either the synchronous or the async version of a filter interface, not both. 프레임 워크를 필터 비동기 인터페이스를 구현 하 고 있다면를 호출 하는 경우 먼저 확인 합니다.The framework 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). 하나의 클래스에 두 인터페이스를 구현 하는 경우, 비동기 메서드가 이라고 합니다.If you were to implement both interfaces on one class, only the async method would be called. 와 같은 추상 클래스를 사용 하는 경우 ActionFilterAttribute 동기 메서드만 또는 각 필터 형식에 대 한 비동기 메서드를 재정의 합니다.When using abstract classes like ActionFilterAttribute you would override only the synchronous methods or the async method for each filter type.

IFilterFactoryIFilterFactory

IFilterFactoryIFilter를 구현합니다.IFilterFactory implements IFilter. 따라서는 IFilterFactory 으로 인스턴스를 사용할 수 있습니다는 IFilter 필터 파이프라인의 아무 곳 이나 인스턴스.Therefore, an IFilterFactory instance can be used as an IFilter instance anywhere in the filter pipeline. 으로 캐스팅을 시도 하는 필터를 호출 하는 프레임 워크를 준비 하는 경우는 IFilterFactory합니다.When the framework prepares to invoke the filter, it attempts to cast it to an IFilterFactory. 해당 캐스트에 성공 하면는 CreateInstance 메서드는 만들려는 IFilter 호출 되는 인스턴스.If that cast succeeds, the CreateInstance method is called to create the IFilter instance that will be invoked. 응용 프로그램이 시작 될 때 명시적으로 설정 하지 않아도 정밀한 필터 파이프라인 이후 유연 하 게 디자인을 제공 합니다.This provides a very flexible design, since the precise filter pipeline does not need to be set explicitly when the application starts.

구현할 수 있습니다 IFilterFactory 필터를 만드는 다른 방법으로 사용자 고유의 특성 구현:You can implement IFilterFactory on your own 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[] { "Header Added" });
        }

        public void OnResultExecuted(ResultExecutedContext context)
        {
        }
    }

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

기본 제공 필터 특성Built-in filter attributes

프레임 워크 하위 클래스를 할 수 있는 기본 제공 특성 기반 필터를 포함 하 고 사용자 지정 합니다.The framework includes built-in attribute-based filters that you can subclass and customize. 예를 들어 다음 결과 필터 응답에 대 한 헤더를 추가 합니다.For example, the following Result filter adds a header to the response.

<a name=add-header-attribute>

using Microsoft.AspNetCore.Mvc.Filters;

namespace FiltersSample.Filters
{
    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 example above. 이 특성을 컨트롤러나 동작 메서드에 추가 하는 이름 및 HTTP 헤더의 값을 지정:You would add this attribute to a controller or action method and specify the name and value of the HTTP header:

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

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

결과 Index 작업 다음과 같습니다.-응답 헤더의 오른쪽 아래에 표시 됩니다.The result of the Index action is shown below - the response headers are displayed on the bottom right.

개발자 도구의 Microsoft Edge 작성자 Steve Smith를 포함 하 여 응답 헤더를 보여 주는@ardalis

여러 필터 인터페이스 사용자 지정 구현에 대 한 기본 클래스로 사용할 수 있는 해당 특성을 가집니다.Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.

필터 속성:Filter attributes:

  • ActionFilterAttribute
  • ExceptionFilterAttribute
  • ResultFilterAttribute
  • FormatFilterAttribute
  • ServiceFilterAttribute
  • TypeFilterAttribute

TypeFilterAttributeServiceFilterAttribute 설명 이 문서의 뒷부분에 나오는합니다.TypeFilterAttribute and ServiceFilterAttribute are explained later in this article.

필터 범위와 실행 순서Filter scopes and order of execution

3 중 하나에서 파이프라인에 필터를 추가할 수 있습니다 범위합니다.A filter can be added to the pipeline at one of three scopes. 특성을 사용 하 여 특정 작업 메서드 또는 컨트롤러 클래스는 필터를 추가할 수 있습니다.You can add a filter to a particular action method or to a controller class by using an attribute. 하거나 추가 하 여 전역적으로 (에 대 한 필터 모든 컨트롤러 및 작업)을 등록할 수 있습니다는 MvcOptions.Filters 컬렉션에는 ConfigureServices 에서 메서드는 Startup 클래스:Or you can register a filter globally (for all controllers and actions) by adding it to the MvcOptions.Filters collection in the ConfigureServices method in the Startup class:

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(SampleActionFilter)); // by type
        options.Filters.Add(new SampleGlobalActionFilter()); // an instance
    });

    services.AddScoped<AddHeaderFilterWithDi>();
}

기본 실행 순서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. 이 라고도 "러시아어 돌" 중첩으로 범위가 증가할 때마다 둘러싸는 앞의 범위와 같은 한 중첩 돌합니다.This is sometimes referred to as "Russian doll" nesting, as each increase in scope is wrapped around the previous scope, like a nesting doll. 일반적으로 명시적으로 순서를 확인할 필요 없이 원하는 재정의 동작을 가져옵니다.You generally get the desired overriding behavior without having to explicitly determine ordering.

이 중첩이의 결과로 의 역순으로에서 실행 되는 필터의 코드는 하기 전에 코드입니다.As a result of this nesting, the after code of filters runs in the reverse order of the before code. 시퀀스는 다음과 같습니다.The sequence looks like this:

  • 전에 전체적으로 적용 된 필터의 코드The before code of filters applied globally
    • 전에 컨트롤러에 적용 된 필터의 코드The before code of filters applied to controllers
      • 전에 작업 메서드에 적용 된 필터의 코드The before code of filters applied to action methods
      • 작업 메서드에 적용 된 필터의 코드The after code of filters applied to action methods
    • 컨트롤러에 적용 된 필터의 코드The after code of filters applied to controllers
  • 전체적으로 적용 된 필터의 코드The after code of filters applied globally

필터 메서드는 동기 작업 필터에 대 한 호출 되는 순서를 보여 주는 예제는 다음과 같습니다.Here's an example that illustrates the order in which filter methods are called for synchronous Action filters.

SequenceSequence 필터 범위Filter scope Filter 메서드Filter method
11 GlobalGlobal OnActionExecuting
22 컨트롤러Controller OnActionExecuting
33 메서드Method OnActionExecuting
44 메서드Method OnActionExecuted
55 컨트롤러Controller OnActionExecuted
66 GlobalGlobal OnActionExecuted

이 시퀀스 메서드 필터 컨트롤러 필터 안에 중첩 되 고 컨트롤러 필터 전역 필터 내에 중첩 되어 있는지를 보여 줍니다.This sequence shows that the method filter is nested within the controller filter, and the controller filter is nested within the global filter. 배치 하 라는 다른 방식으로, 비동기 필터 내 인 경우의 온단계ExecutionAsync 메서드 긴밀 하 게 범위를 사용 하 여 필터의 모든 코드를 실행 스택에 있습니다.To put it another way, if you're inside an async filter's OnStageExecutionAsync method, all of the filters with a tighter scope run while your code is on the stack.

참고

상속 되는 모든 컨트롤러는 Controller 기본 클래스에 OnActionExecutingOnActionExecuted 메서드.Every controller that inherits from the Controller base class includes OnActionExecuting and OnActionExecuted methods. 이러한 메서드를 실행 하는 지정된 된 동작에 대 한 필터를 래핑할: OnActionExecuting 에서 필터 보다 먼저 호출 됩니다 및 OnActionExecuted 모든 필터 후에 호출 됩니다.These methods wrap the filters that run for a given action: OnActionExecuting is called before any of the filters, and OnActionExecuted is called after all of the filters.

기본 순서를 재정의합니다.Overriding the default order

구현 하 여 실행의 기본 시퀀스를 재정의할 수 있습니다 IOrderedFilter합니다.You can override the default sequence of execution by implementing IOrderedFilter. 이 인터페이스를 노출 한 Order 실행 순서를 결정 하는 범위에 대해 우선 순위를 사용 하는 속성입니다.This interface exposes an Order property that takes precedence over scope to determine the order of execution. 낮은 필터 Order 값은 해당 하기 전에 그의 더 큰 값 필터 전에 실행 되는 코드 Order합니다.A filter with a lower Order value will have its before code executed before that of a filter with a higher value of Order. 낮은 필터 Order 값은 해당 코드를 실행 하는 더 높은 사용 하 여 필터 Order 값입니다.A filter with a lower Order value will have its after code executed after that of a filter with a higher Order value. 설정할 수 있습니다는 Order 생성자 매개 변수를 사용 하 여 속성:You can set the Order property by using a constructor parameter:

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

동일한 첫 번째 집합 제외한 위의 예제에 표시 된 3 작업 필터가 있는 경우는 Order 각각 1과 2에 필터는 컨트롤러 및 글로벌 속성, 실행의 순서를 바꿀 수는 있습니다.If you have the same 3 Action filters shown in the preceding example but set the Order property of the controller and global filters to 1 and 2 respectively, the order of execution would be reversed.

SequenceSequence 필터 범위Filter scope Order 속성Order property Filter 메서드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 trumps scope when determining the order in which filters will run. 필터 순서에 따라 먼저 정렬 한 후 범위는 결속을 끊을 하는 데 사용 됩니다.Filters are sorted first by order, then scope is used to break ties. 기본 제공 필터를 모두 구현 IOrderedFilter 기본 설정 및 Order 값을 0으로 설정 하지 않으면 범위 순서를 결정 하므로 Order 0이 아닌 값으로.All of the built-in filters implement IOrderedFilter and set the default Order value to 0, so scope determines order unless you set Order to a non-zero value.

취소 및 짧은 단락 circuitCancellation and short circuiting

설정 하 여 언제 든 지 필터 파이프라인을 단락 수는 Result 속성에는 context 필터 메서드에 제공 된 매개 변수입니다.You can short-circuit the filter pipeline at any point by setting the Result property on the context parameter provided to the filter method. 예를 들어, 다음과 같은 리소스 필터 파이프라인의 나머지 부분에서 실행 되지 않도록합니다.For instance, the following Resource filter prevents the rest of the pipeline from executing.

<a name=short-circuiting-resource-filter>

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FiltersSample.Filters
{
    public class ShortCircuitingResourceFilterAttribute : Attribute,
            IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            context.Result = new ContentResult()
            {
                Content = "Resource unavailable - header should not be 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 먼저 실행 (리소스 필터 이기 때문에 및 AddHeader 작업 필터는) 파이프라인의 나머지 short-circuits 및는 AddHeader 필터에 대 한 실행 되지 않도록는 SomeResource 동작 합니다.However, because the ShortCircuitingResourceFilter runs first (because it is a Resource Filter and AddHeader is an Action Filter) and short-circuits the rest of the pipeline, the AddHeader filter never runs for the SomeResource action. 이 동작은 두 필터는 제공 된 동작 메서드 수준에서 적용 된 경우 동일한 될를 ShortCircuitingResourceFilter 첫 번째 실행 (필터 형식을 인해 또는 명시적 활용 Order 속성, 예를 들어).This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first (because of its filter type, or explicit use of Order property, for instance).

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

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

종속성 주입Dependency injection

유형 또는 인스턴스가 필터를 추가할 수 있습니다.Filters can be added by type or by instance. 인스턴스를 추가 하는 경우 해당 인스턴스가 모든 요청에 대해 사용 됩니다.If you add an instance, that instance will be used for every request. 종류를 추가 하면 됩니다 형식 활성, 즉 각 요청에 대 한 인스턴스를 만들 수는 되 고 모든 생성자 종속성에 의해 채워지는 종속성 주입 (DI).If you add a type, it will be type-activated, meaning an instance will be created for each request and any constructor dependencies will be populated by dependency injection (DI). 에 해당 하는 형식으로 필터를 추가 filters.Add(new TypeFilterAttribute(typeof(MyFilter)))합니다.Adding a filter by type is equivalent to filters.Add(new TypeFilterAttribute(typeof(MyFilter))).

특성으로 구현 되어 컨트롤러 클래스 또는 동작 메서드를 직접 추가 하는 필터에서 제공 하는 생성자 종속성이 하 여야 종속성 주입 (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). 특성에 적용 되는 위치를 제공 하는 생성자 매개 변수의 있어야 하기 때문입니다.This is because attributes must have their constructor parameters supplied where they are applied. 특성이 작동 되는 방법의 제한 사항입니다.This is a limitation of how attributes work.

필터에 종속성 DI에서 액세스 해야 하는 경우 지원 되는 여러 가지 방법으로 있습니다.If your filters have dependencies that you need to access from DI, there are several supported approaches. 다음 중 하나를 사용 하 여 클래스 또는 동작 메서드에 필터를 적용할 수 있습니다.You can apply your filter to a class or action method using one of the following:

  • ServiceFilterAttribute
  • TypeFilterAttribute
  • IFilterFactory특성에 구현IFilterFactory implemented on your attribute

참고

DI에서 가져올 하려는 경우 종속성을 하나는 거입니다.One dependency you might want to get from DI is a logger. 그러나 만들고 이후 로깅 용도로 필터를 사용 하를 사용 하지는 기본 제공 프레임 워크 로깅 기능이 필요한 이미 제공 될 수 있습니다.However, avoid creating and using filters purely for logging purposes, since the built-in framework logging features may already provide what you need. 필터에 로깅을 추가 하려는 경우 비즈니스 도메인 문제나 또는 필터를 보다는 MVC 동작 또는 다른 프레임 워크 이벤트에 대 한 동작에 집중 해야 합니다.If you're going to add logging to your filters, it should focus on business domain concerns or behavior specific to your filter, rather than MVC actions or other framework events.

ServiceFilterAttributeServiceFilterAttribute

A ServiceFilter DI에서 필터의 인스턴스를 검색 합니다.A ServiceFilter retrieves an instance of the filter from DI. 필터에서 컨테이너를 추가 ConfigureServices, 참조에 ServiceFilter 특성You add the filter to the container in ConfigureServices, and reference it in a ServiceFilter attribute

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(SampleActionFilter)); // by type
        options.Filters.Add(new SampleGlobalActionFilter()); // an instance
    });

    services.AddScoped<AddHeaderFilterWithDi>();
}
[ServiceFilter(typeof(AddHeaderFilterWithDi))]
public IActionResult Index()
{
    return View();
}

사용 하 여 ServiceFilter 예외에서 필터 형식 결과 등록 하지 않고:Using ServiceFilter without registering the filter type results in an exception:

System.InvalidOperationException: No service for type
'FiltersSample.Filters.AddHeaderFilterWithDI' has been registered.

ServiceFilterAttribute구현 IFilterFactory를 만들기 위한 단일 메서드를 노출 하는 프로그램 IFilter 인스턴스.ServiceFilterAttribute implements IFilterFactory, which exposes a single method for creating an IFilter instance. 경우 ServiceFilterAttribute, IFilterFactory 인터페이스의 CreateInstance 메서드는 지정된 된 형식의 서비스 컨테이너 (DI)에서 로드 합니다.In the case of ServiceFilterAttribute, the IFilterFactory interface's CreateInstance method is implemented to load the specified type from the services container (DI).

TypeFilterAttributeTypeFilterAttribute

TypeFilterAttribute매우 비슷하지만 ServiceFilterAttribute (하며 구현 IFilterFactory), 하지만 DI 컨테이너에서 직접 해당 형식을 확인할 수 없습니다.TypeFilterAttribute is very similar to ServiceFilterAttribute (and also implements IFilterFactory), but its type is not resolved directly from the DI container. 사용 하 여 형식을 인스턴스화합니다 대신 Microsoft.Extensions.DependencyInjection.ObjectFactory합니다.Instead, it instantiates the type by using Microsoft.Extensions.DependencyInjection.ObjectFactory.

형식 사용 하 여 참조 되는 이러한 차이로 인해는 TypeFilterAttribute 먼저 컨테이너를 사용 하 여 등록할 필요가 없습니다 (하지만 컨테이너에 의해 충족 종속성 수는 여전히).Because of this difference, types that are referenced using the TypeFilterAttribute do not need to be registered with the container first (but they will still have their dependencies fulfilled by the container). 또한 TypeFilterAttribute 해당 형식에 대 한 생성자 인수를 필요에 따라 허용할 수 있습니다.Also, TypeFilterAttribute can optionally accept constructor arguments for the type in question. 다음 예제에는 인수를 사용 하 여 형식을 전달 하는 방법을 보여 줍니다 TypeFilterAttribute:The following example demonstrates how to pass arguments to a type using TypeFilterAttribute:

[TypeFilter(typeof(AddHeaderAttribute),
    Arguments = new object[] { "Author", "Steve Smith (@ardalis)" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}

경우는 인수가 필요 하지 않은 필터 하지만 DI에서 메꾸어야 할 생성자 종속성이 있는 사용할 수 있습니다 직접 명명 된 특성 클래스 및 메서드 대신에 [TypeFilter(typeof(FilterType))]).If you have a filter that doesn't require any arguments, but which has constructor dependencies that need to be filled by DI, you can use your own named attribute on classes and methods instead of [TypeFilter(typeof(FilterType))]). 다음 필터는이 구현할 수 있는 방법을 보여 줍니다.The following filter shows how this can be implemented:

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] 구문을 사용 하는 대신 [TypeFilter] 또는 [ServiceFilter]합니다.This filter can be applied to classes or methods using the [SampleActionFilter] syntax, instead of having to use [TypeFilter] or [ServiceFilter].

권한 부여 필터Authorization filters

권한 부여 필터 동작 메서드에 대 한 액세스를 제어 하 고 첫 번째 필터를 필터 파이프라인 내에서 실행 됩니다.Authorization filters control access to action methods and are the first filters to be executed within the filter pipeline. 만 있는 메서드를 지 원하는 메서드 전후 대부분 필터와 달리 하기 전에.They have only a before method, unlike most filters that support before and after methods. 만 작성 해야 사용자 지정 권한 부여 필터는 자신의 권한 부여 프레임 워크를 작성 하는 경우.You should only write a custom authorization filter if you are writing your own authorization framework. 권한 부여 정책을 구성 하거나 사용자 지정 필터를 작성 하는 대신 사용자 지정 권한 부여 정책 작성을 선호 합니다.Prefer configuring your authorization policies or writing a custom authorization policy over writing a custom filter. 기본 제공 필터를 구현 하면은 권한 부여 시스템을 호출 합니다.The built-in filter implementation is just responsible for calling the authorization system.

예외 처리는 아무것도 때문에 권한 부여 필터 내에서 예외 throw 하지 않아야 참고 (예외 필터 처리할 수 없는 해당).Note that you should not throw exceptions within authorization filters, since nothing will handle the exception (exception filters won't handle them). 대신, 챌린지를 발급 하거나 다른 해결 방법의 찾을 합니다.Instead, issue a challenge or find another way.

에 대 한 자세한 내용은 권한 부여합니다.Learn more about Authorization.

자원 필터Resource filters

자원 필터 구현 중 하나는 IResourceFilter 또는 IAsyncResourceFilter 인터페이스 및 해당 실행 필터 파이프라인의 대부분을 래핑합니다.Resource filters implement either the IResourceFilter or IAsyncResourceFilter interface, and their execution wraps most of the filter pipeline. (만 권한 부여 필터 앞 실행 합니다.) 리소스 필터는 대부분의 작업 요청을 수행 하는 작업은 단락 (short-circuit) 하는 경우에 특히 유용 합니다.(Only Authorization filters run before them.) Resource filters are especially useful if you need to short-circuit most of the work a request is doing. 예를 들어 캐싱 필터 응답 캐시에 이미 있으면 파이프라인의 나머지 부분을 방지할 수 있습니다.For example, a caching filter can avoid the rest of the pipeline if the response is already in the cache.

짧은 단락 circuit 리소스 필터 리소스 필터의 예로 앞에서 살펴본 합니다.The short circuiting resource filter shown earlier is one example of a resource filter. 또 다른 예로 DisableFormValueModelBindingAttribute, 모델 바인딩 양식 데이터에 액세스할 수 없습니다.Another example is DisableFormValueModelBindingAttribute, which prevents model binding from accessing the form data. 대형 파일 업로드를 받아서 폼 메모리로 읽어 하지 못하게 하려면 수 거 알고 있는 경우에 유용 합니다.It's useful for cases where you know that you're going to receive large file uploads and want to prevent the form from being read into memory.

작업 필터Action filters

작업 필터 구현 중 하나는 IActionFilter 또는 IAsyncActionFilter 인터페이스 및 해당 실행 주위의 작업 메서드의 실행 합니다.Action filters implement either the IActionFilter or IAsyncActionFilter interface, and their execution surrounds the execution of action methods.

샘플 작업 필터는 다음과 같습니다.Here's a sample action filter:

public class SampleActionFilter : 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 - lets you manipulate the inputs to the action.
  • Controller-컨트롤러 인스턴스를 조작할 수 있습니다.Controller - lets you manipulate the controller instance.
  • Result-작업 메서드 및 후속 작업 필터의 실행 short-circuits이 설정 합니다.Result - setting this short-circuits execution of the action method and subsequent action filters. 예외를 throw 또한 동작 메서드 및 후속 필터의 실행을 방지 하지만 대신 성공적인 결과 실패로 처리 됩니다.Throwing an exception also prevents execution of the action method and subsequent filters, but is treated as a failure instead of a successful result.

ActionExecutedContext 제공 ControllerResult 다음과 같은 속성 및:The ActionExecutedContext provides Controller and Result plus the following properties:

  • Canceled-다른 필터에 의해 액션 실행 short-circuited가 true입니다.Canceled - will be true if the action execution was short-circuited by another filter.
  • Exception-작업 또는 후속 작업 필터에서 예외가 null이 아닌 됩니다.Exception - will be non-null if the action or a subsequent action filter threw an exception. 이 속성을 효과적으로 null로 설정 'handles' 예외를 및 Result 경우 정상적으로 동작 메서드에서 반환 된 것 처럼 실행 됩니다.Setting this property to null effectively 'handles' an exception, and Result will be executed as if it were returned from the action method normally.

에 대 한는 IAsyncActionFilter에 대 한 호출에서 ActionExecutionDelegate 모든 후속 작업 필터를 실행 하는 반환 된 작업 메서드는 ActionExecutedContext합니다.For an IAsyncActionFilter, a call to the ActionExecutionDelegate executes any subsequent action filters and the action method, returning an ActionExecutedContext. 단락 (short-circuit)를 할당 하려면 ActionExecutingContext.Result 일부 결과에 인스턴스를 호출 하지 않으면는 ActionExecutionDelegate합니다.To short-circuit, assign ActionExecutingContext.Result to some result instance and do not call the ActionExecutionDelegate.

프레임 워크는 추상 제공 ActionFilterAttribute 하위 클래스를 할 수 있습니다.The framework provides an abstract ActionFilterAttribute that you can subclass.

자동으로 모델 상태를 확인 하 고 상태에 유효 하지 않을 경우 오류를 반환 하는 작업 필터를 사용할 수 있습니다.You can use an action filter to automatically validate model state and return any errors if the state is invalid:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FiltersSample.Filters
{
    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                context.Result = new BadRequestObjectResult(context.ModelState);
            }
        }
    }
}

OnActionExecuted 보고를 통해 작업의 결과 조작 메서드를 실행 한 후 작업 메서드와 수 있습니다는 ActionExecutedContext.Result 속성입니다.The OnActionExecuted method runs after the action method and can see and manipulate the results of the action through the ActionExecutedContext.Result property. ActionExecutedContext.Canceled다른 필터에 의해 액션 실행 short-circuited 된 경우 true로 설정 됩니다.ActionExecutedContext.Canceled will be set to true if the action execution was short-circuited by another filter. ActionExecutedContext.Exception작업 또는 후속 작업 필터에서 예외가 null이 아닌 값으로 설정 됩니다.ActionExecutedContext.Exception will be set to a non-null value if the action or a subsequent action filter threw an exception. 설정 ActionExecutedContext.Exception 효과적으로 null로 'handles', 예외 및 ActionExectedContext.Result 경우 정상적으로 동작 메서드에서 반환 된 것 처럼 실행할 수 있습니다.Setting ActionExecutedContext.Exception to null effectively 'handles' an exception, and ActionExectedContext.Result will then be executed as if it were returned from the action method normally.

예외 필터Exception filters

예외 필터 구현 중 하나는 IExceptionFilter 또는 IAsyncExceptionFilter 인터페이스입니다.Exception filters implement either the IExceptionFilter or IAsyncExceptionFilter interface. 일반적인 오류 처리 응용 프로그램에 대 한 정책을 구현 하려면 사용할 수 있습니다.They can be used to implement common error handling policies for an app.

다음 샘플 예외 필터는 사용자 지정 개발자 오류 보기를 사용 하 여 응용 프로그램 개발 중인 경우에 발생 하는 예외에 대 한 정보를 표시 하려면:The following sample exception filter uses a custom developer error view to display details about exceptions that occur when the application 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())
        {
            // do nothing
            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;
    }
}

예외 필터는 두 개의 이벤트가 (전 및 후)-구현만 OnException (또는 OnExceptionAsync).Exception filters do not have two events (for before and after) - they only implement OnException (or OnExceptionAsync).

컨트롤러 만들기에서 발생 하는 처리 되지 않은 예외를 처리 하는 예외 필터 모델 바인딩, 작업 메서드 또는 작업 필터.Exception filters handle unhandled exceptions that occur in controller creation, model binding, action filters, or action methods. 리소스 필터, 결과 필터 또는 MVC 결과 실행에서 발생 하는 예외를 catch 하지 않습니다.They won't catch exceptions that occur in Resource filters, Result filters, or MVC Result execution.

예외를 처리 하려면 설정는 ExceptionContext.ExceptionHandled 속성을 true 또는 응답을 작성 합니다.To handle an exception, set the ExceptionContext.ExceptionHandled property to true or write a response. 그러면 예외는 전파 되지 않습니다.This stops propagation of the exception. 참고 예외 필터는 "성공"으로 예외를 설정할 수 없습니다.Note that an Exception filter can't turn an exception into a "success". 작업 필터를 작업을 수행할 수 있습니다.Only an Action filter can do that.

참고

ASP.NET 1.1에서는 응답 보내집니다 설정 하면 ExceptionHandled true로 응답을 작성 합니다.In ASP.NET 1.1, the response is not sent if you set ExceptionHandled to true and write a response. 이 시나리오에서 ASP.NET Core 1.0는 응답을 전송 하 고 ASP.NET Core 1.1.2 1.0 동작으로 반환 됩니다.In that scenario, ASP.NET Core 1.0 does send the response, and ASP.NET Core 1.1.2 will return to the 1.0 behavior. 자세한 내용은 참조 #5594 발급 GitHub 리포지토리에 합니다.For more information, see issue #5594 in the GitHub repository.

예외 필터는 MVC 동작 내에서 발생 하는 예외를 트래핑 하는 데 유용 하지만 유연 하 게 오류 미들웨어를 처리 하지 않습니다.Exception filters are good for trapping exceptions that occur within MVC actions, but they're not as flexible as error handling middleware. 일반적인 경우에 대 한 미들웨어를 선호 하 고만 해야 하는 필터를 사용 하 여 오류 처리 작업을 수행할 다르게 MVC 작업 선택에 따라 합니다.Prefer middleware for the general case, and use filters only where you need to do error handling differently based on which MVC action was chosen. 예를 들어 앱에는 뷰/HTML 및 API 끝점 모두에 대 한 동작 메서드가 있을 수 있습니다.For example, your app might have action methods for both API endpoints and for views/HTML. API 끝점 보기 기반 동작 html 오류 페이지가 반환 될 수 하는 동안 JSON으로 오류 정보를 반환할 수 있습니다.The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.

프레임 워크는 추상 제공 ExceptionFilterAttribute 하위 클래스를 할 수 있습니다.The framework provides an abstract ExceptionFilterAttribute that you can subclass.

결과 필터Result filters

필터 결과 구현 중 하나는 IResultFilter 또는 IAsyncResultFilter 인터페이스 및 해당 실행 주위의 작업 결과 실행 합니다.Result filters implement either the IResultFilter or IAsyncResultFilter interface, and their execution surrounds the execution of action results.

HTTP 헤더를 추가 하는 결과 필터의 예를 들면 다음과 같습니다.Here's an example of a Result filter that adds an HTTP header.

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

    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 already begun.
    }
}

실행 되 고 결과의 종류에는 동작에 따라 다릅니다.The kind of result being executed depends on the action in question. 뷰를 반환 하는 MVC 동작의 일부로 처리 하는 모든 razor 포함는 ViewResult 실행 되 고 있습니다.An MVC action returning a view would include all razor processing as part of the ViewResult being executed. API 메서드는 실행 결과의 일부로 일부 serialization을 수행할 수 있습니다.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.

OnResultExecuting 메서드 수 단락 (short-circuit) 작업 결과 및 후속 결과 필터의 실행을 설정 하 여 ResultExecutingContext.Cancel true로 합니다.The OnResultExecuting method can short-circuit execution of the action result and subsequent result filters by setting ResultExecutingContext.Cancel to true. 일반적으로 빈 응답을 생성 하지 않도록 단락 (short-circuiting) 하는 경우 응답 개체를 작성 해야 합니다.You should generally write to the response object when short-circuiting to avoid generating an empty response. 예외를 throw 작업 결과 및 후속 필터의 실행도 못합니다 하지만 대신 성공적인 결과 실패로 처리 됩니다.Throwing an exception will also prevent execution of the action result and subsequent filters, but will be treated as a failure instead of a successful result.

경우는 OnResultExecuted 메서드 실행, 응답 가능성이 클라이언트에 전송 되어 고 (없는 경우 예외가 throw 되었습니다) 추가로 변경할 수 없습니다.When the OnResultExecuted method runs, the response has likely been sent to the client and cannot be changed further (unless an exception was thrown). ResultExecutedContext.Canceled작업 결과가 실행 된 다른 필터에 의해 short-circuited 하는 경우 true로 설정 됩니다.ResultExecutedContext.Canceled will be set to true if the action result execution was short-circuited by another filter.

ResultExecutedContext.Exception작업 결과 또는 후속 결과 필터에서 예외가 null이 아닌 값으로 설정 됩니다.ResultExecutedContext.Exception will be set to a non-null value if the action result or a subsequent result filter threw an exception. 설정 Exception 를 null에서 효과적으로 예외 ' handles' 하 고 하면 예외가 MVC 파이프라인의 뒷부분에 나오는 예외가 다시 throw 되지 않습니다.Setting Exception to null effectively 'handles' an exception and prevents the exception from being rethrown by MVC later in the pipeline. 결과 필터에서 예외를 처리 하는 경우 응답에 모든 데이터를 쓸 수 없습니다.When you're handling an exception in a result filter, you might not be able to write any data to the response. 작업 결과가 실행을 통해 충족할 throw 하는 경우 헤더 이미 플 리 시 된 클라이언트에 오류 코드를 전송 하는 신뢰할 수 있는 메커니즘이 있습니다.If the action result throws partway through its execution, and the headers have already been flushed to the client, there's no reliable mechanism to send a failure code.

에 대 한 프로그램 IAsyncResultFilter 에 대 한 호출 await next()ResultExecutionDelegate 모든 후속 결과 필터를 실행 하는 작업 결과입니다.For an IAsyncResultFilter a call to await next() on the ResultExecutionDelegate executes any subsequent result filters and the action result. 단락 (short-circuit)를 설정 하려면 ResultExecutingContext.Cancel 를 호출 하지 마십시오 하 고 true는 ResultExectionDelegate합니다.To short-circuit, set ResultExecutingContext.Cancel to true and do not call the ResultExectionDelegate.

프레임 워크는 추상 제공 ResultFilterAttribute 하위 클래스를 할 수 있습니다.The framework provides an abstract ResultFilterAttribute that you can subclass. AddHeaderAttribute 앞에 표시 된 클래스는 결과 필터 특성의 예시입니다.The AddHeaderAttribute class shown earlier is an example of a result filter attribute.

필터 파이프라인에 미들웨어를 사용 하 여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. 하지만 MVC 컨텍스트 및 구문에 액세스할 수 있는 즉 MVC의 일부인 한다는 점에서 필터 미들웨어에서 다릅니다.But filters differ from middleware in that they are part of MVC, which means that they have access to MVC context and constructs.

ASP.NET Core 1.1에서는 필터 파이프라인에 미들웨어를 사용할 수 있습니다.In ASP.NET Core 1.1, you can use middleware in the filter pipeline. MVC 경로 데이터 또는 컨트롤러 또는 작업을 특정 실행 해야 하는 하나에 액세스 해야 하는 미들웨어 구성 요소를 설정한 경우 작업을 수행 하 고 좋습니다.You might want to do that if you have a middleware component that needs access to MVC route data, or one that should run only for certain controllers or actions.

미들웨어를 필터로 사용 하려면 형식을 만듭니다는 Configure 필터 파이프라인에 삽입 하려고 하는 미들웨어를 지정 하는 메서드.To use middleware as a filter, create a type with a Configure method that specifies the middleware that you want to inject into the filter pipeline. 요청에 대 한 현재 문화권을 설정 하는 지역화 미들웨어를 사용 하는 예제는 다음과 같습니다.Here's an example that 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 선택한 컨트롤러 또는 동작에 대 한 미들웨어를 실행 하려면 또는 전역:You can then use the MiddlewareFilterAttribute to run the middleware for a selected controller or action or globally:

[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

필터를 시험해 다운로드, 테스트 및 예제를 수정합니다.To experiment with filters, download, test and modify the sample.