Filters

blimeyoops·2023년 9월 20일
0

asp.net core

목록 보기
3/4

ASP.NET Core MVC에서는 필터(Filters)를 이용해 특정 단계(전역, 컨트롤러, 액션 별로 각각 구성) 전후에 원하는 코드를 실행할 수 있다. 이런 점에 있어서 필터와 미들웨어는 차이점이 있다.

필터와 미들웨어 차이

미들웨어는 HttpContext에 액세스할 수 있고 필터는 더 넓은 MVC 컨텍스트에까지 액세스할 수 있다. 즉, 필터는 동작의 범위를 지정할 수 있고, 뷰 처리 직전이나 모델 바인딩 이후 같은 응용 프로그램 내부의 적절한 위치에 삽입이 가능하다. 또한 필터는 MVC의 일부로서 MVC 컨텍스트와 구조에 접근할 수 있다.

요청 실행이 시작되면 미들웨어를 통과하고 미들웨어에서 다른 미들웨어로 요청을 전달하고 결국 미들웨어 요청 후에 MVC 파이프라인으로 들어가 필터를 거치게 된다.

필터 종류

종류설명
Authorization 필터현재 사용자가 지금 처리 중인 요청에 대한 권한을 부여 받았는지 여부를 판단할 때 사용
Resource 필터권한이 부여된 이후에 요청을 처리하는 가장 첫 번째 필터이자, 필터 파이프라인을 빠져 나갈때 요청에 관여할 수 있는 가장 마지막 필터
이 필터는 캐싱을 구현하거나, 성능상의 목적으로 필터 파이프라인을 신속하게 빠져나가야 할 때 특히 유용
Action 필터액션 메서드에 대한 호출을 감싸고, 액션으로 전달되는 인자나 반환되는 액션 결과를 조정
Exception 필터처리되지 않은 예외에 대한 MVC 응용 프로그램의 전역 정책을 적용할 때 사용
Result 필터개별 액션 결과(Action Results)의 실행을 감싸며, 액션 메서드가 정상적으로 실행된 경우에만 실행, 뷰 실행이나 포맷터 실행을 감싸는 로직을 구현하기에 적합한 단계

필터 동작 방식

위의 다양한 필터들은 파이프라인의 각기 다른 시점에 실행된다.

  • Authorization 필터
    다른 필터들 보다 가장 먼저 실행된다.
  • Resource 필터
    Authorization 필터 이후에 실행된다.
    OnResourceExecuting 메서드는 다른 필터 파이프라인보다 먼저 코드를 실행한다.
    OnResourceExecuted 메서드는 파이프라인의 나머지 부분이 완료된 후에 코드를 실행한다.
  • Action 필터
    액션 메서드가 호출되기 전후에 즉시 실행된다.

  • Result 필터
    액션 결과가 실행되지 전후에 즉시 실행된다.

  • Exception 필터
    다른 필터들이나 액션 메서드, 액션 결과가 예를 던지는 경우에만 실행된다.

구현

필터는 동기 구현과 비동기 구현 모두 작성할 수 있다. 만약 한 클래스에 두 가지 인터페이스를 모두 구현한다면 비동기 메서드만 호출된다.

  • Authorization 필터
    동기 메서드: OnAuthorization
    비동기 메서드: OnAuthorizationAsync

  • Resource 필터
    동기 메서드: OnResourceExecuted, OnResourceExecuting
    비동기 메서드: OnResourceExecutionAsync

  • Action 필터
    동기 메서드: OnActionExecuted, OnActionExecuting
    비동기 메서드: OnActionExecutionAsync

  • Result 필터
    동기 메서드: OnResultExecuted, OnResultExecuting
    비동기 메서드: OnResultExecutionAsync

  • Exception 필터
    동기 메서드: OnException
    비동기 메서드: OnExceptionAsync

Executing으로 끝나는 메서드는 파이프라인 단계 이전에 호출되고, Executed으로 끝나는 메서드는 파이프라인 단계 이후에 호출된다.

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
    }
}

비동기 필터는 단일 메서드 하나만 제공되고 메서드 호출 후 대기 중일때 실행 되는 대리자를 구현하면 된다.

public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 
{
    // do something before the action executes
    await next();
    // do something after the action executes
}

필터 범위

필터는 전역, 컨트롤러, 액션 메서드의 범위로 설정 가능하고 다음과 같은 순서로 동작한다.

순서범위메서드
1전역OnActionExecuting
2컨트롤러OnActionExecuting
3액션 메서드OnActionExecuting
4액션 메서드OnActionExecuted
5컨트롤러OnActionExecuted
6전역OnActionExecuted

전역 범위 설정은 Startup 클래스 또는 program 클래스의 ConfigureServices 메서드에서 MVC를 구성할 때 추가하고, 컨트롤러, 액션 메서드의 필터 사용은 Attributes 형태로 사용된다.

예를 들어, IActionFilter를 상속받아 ActionFilter를 구현한다.

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("OnActionExecuted");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("OnActionExecuting");
    }
}

컨트롤러의 Index 액션 메서드를 다음과 같이 수정한다.

public IActionResult Index()
{
    Console.WriteLine("Index...");
    return View();
}

전역에 설정 하기위해 program 클래스에 다음을 추가한다.

builder.Services.AddMvcCore(options =>
{
    options.Filters.Add(new SampleActionFilter());
});
builder.Services.AddScoped<SampleActionFilter>();

웹 어플리케이션을 실행하면 콘솔에 OnActionExecuting -> Index -> OnActionExecuted 순으로 실행된 것을 확인할 수 있다.

컨트롤러 및 액션 메서드에 어트리뷰트로 필터를 정의하기 위해서는 ActionFilterAttribute를 상속받아 구현한다.

public class SampleActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("OnActionExecuted...");
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("OnActionExecuting...");
    }
}

컨트롤러에 어트리뷰트를 사용해 필터를 적용한다.

[SampleAction]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        Console.WriteLine("Index...");
        return View();
    }
}

웹 어플리케이션을 실행하면 전역에 필터를 적용한 결과 동일하다.

0개의 댓글

관련 채용 정보