액션 필터 이해하기
이번 자습서는 액션 필터에 대해 설명합니다. 액션 필터란 컨트롤러의 특정 액션 또는 컨트롤러의 전체 액션에 적용할 수 있는 어트리뷰트를 말하는데요. 이러한 어트리뷰트를 적용하면 액션이 수행되는 방식을 변경할 수 있습니다. ASP.NET MVC 프레임워크는 다음의 몇 가지 액션 필터를 제공하고 있습니다.
- OutputCache - 지정된 시간 동안 컨트롤러의 액션 결과를 캐시하는 액션 필터
- HandleError - 컨트롤러 액션이 수행되는 도중 발생한 에러를 처리하기 위해 사용되는 액션 필터
- Authorize - 특정 사용자 또는 그룹으로만 접근을 제한시키는 액션 필터
또한, 여러분은 여러분만의 고유한 사용자 정의 액션 필터를 만들 수도 있습니다. 예를 들면, 회사 고유의 인증 방식을 구현하기 위해, 또는 컨트롤러 액션이 반환하는 뷰 데이터를 수정하기 위해 사용자 정의 액션 필터를 고려해 볼 수 있습니다.
이번 자습서에서는 어떻게 사용자 액션 필터를 작성하는지 기초부터 단계적으로 배우게 됩니다. 우리는 Log 라는 액션 필터를 만들어 볼텐데, 이 액션 필터는 액션이 수행되는 상황을 순서대로 비주얼 스튜디오의 Output 창에 출력합니다.
액션 필터 사용하기
액션 필터는 어트리뷰트입니다. 그렇기에, 대부분의 액션 필터들을 특정 컨트롤러나 전체 컨트롤러에 적용할 수 있습니다.
예를 들면, 목록 1의 Data 컨트롤러는 현재 시간을 반환하는Index() 라는 액션을 노출하고 있고, 이 액션에는OutputCache 액션 필터가 적용되어 있습니다. 이 필터는 액션에 의해 반환되는 값이 10초 동안 캐시되도록 만듭니다.
목록 1 - Controllers\DataController.cs
using System;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class DataController : Controller
{
[OutputCache(Duration=10)]
public string Index()
{
return DateTime.Now.ToString("T");
}
}
}
/Data/Index을 브라우저에 입력하고 페이지를 새로 고침하면서Index() 메서드를 계속 호출해 보면 같은 시간을 10초 동안 계속 보게 될겁니다. Index() 액션의 출력 값이 10초 동안 캐시로 유지되기 때문입니다.

출처 : http://i1.asp.net/asp.net/images/mvc/14/Images/mvc_tutorial14_cs_figure01.png
목록 1에서는 하나의 액션 필터, 즉, OutputCache가Index() 메서드에 적용되어 있지만, 필요하다면 여러 개의 액션 필터를 적용할 수도 있습니다. 같은 액션에 액션 필터OutputCache 와 HandleError를 동시에 적용하는 것이 그 예입니다.
목록 1에서는 OutputCache액션 필터가Index() 액션에 적용되어 있습니다만, 원한다면, 이 어트리뷰트를 DataController클래스에 적용할 수도 있습니다. 클래스에 어트리뷰트가 적용되면, 그 클래스에 있는 모든 액션의 결과 값은 10초 동안 캐시될 겁니다.
여러 종류의 필터들
ASP.NET MVC 프레임워크는 네 종류의 필터를 지원합니다.
- 권한 필터 - IAuthorizationFilter 인터페이스를 구현하는 어트리뷰트
- 액션 필터 - IActionFilter인터페이스를 구현하는 어트리뷰트
- 결과 필터 - IResultFilter인터페이스를 구현하는 어트리뷰트
- 예외 필터 - IExceptionFilter인터페이스를 구현하는 어트리뷰트
역자 주 : 잠시 후 다시 언급하겠습니다만, "액션 필터"라는 용어는 좀 더 광범위하게는 모든 종류의 필터를 통칭하기도 한답니다. 따라서, 문맥에 따라 일반적인 필터를 의미하는지 또는 액션 필터라는 특정 형태의 필터를 의미하는지 구분할 수 있어야 합니다
필터들은 위에 언급된 순서대로 실행됩니다. 예를 들면, 권한 필터는 항상 액션 필터보다 먼저 실행되고 예외 필터는 항상 모든 필터 다음에 실행됩니다.
권한 필터는 컨트롤러 액션의 인증과 권한을 구현하는데 사용됩니다. Authorize 필터는 권한 필터의 한 예입니다.
액션 필터는 컨트롤러 액션이 실행되는 시점을 기준으로 그 전과 후에 실행할 수 있는 로직을 포함합니다. 예를 들어, 액션이 반환하는 뷰의 데이터를 변경하고자 할 경우에 액션 필터를 사용할 수 있습니다.
결과 필터는 뷰의 결과가 실행되는 시점을 기준으로 그 전과 후에 실행할 수 있는 로직을 포함합니다. 뷰가 브라우저에 렌더링되기 직전에 뷰의 결과를 수정하고 싶다면 결과 필터를 사용하면 됩니다.
예외 필터는 마지막으로 실행되는 필터입니다. 개발자는 액션 또는 액션 결과에서 발생하는 오류를 처리하기 위해 이 필터를 사용할 수 있습니다. 또한, 오류를 기록하기 위해서 예외 필터를 사용할 수도 있습니다.
각각의 필터 형태는 특정 순서대로 실행됩니다. 동일한 유형의 필터가 실행되는 순서를 조정하고자 할 때는 필터의 Order 속성을 지정하면 됩니다.
모든 액션 필터의 기본 클래스는System.Web.Mvc.FilterAttribute 클래스 입니다. 여러분만의 특정 필터를 구현하고자 한다면 이 기본 클래스를 상속하는 클래스를 생성하고, 다음 인터페이스들 중 하나 이상의 인터페이스를 구현하면 됩니다. IAuthorizationFilter, IActionFilter, IResultFilter, IExceptionFilter.
기본 클래스 - ActionFilterAttribute
ASP.NET MVC 프레임워크는 개발자가 사용자 정의 액션 필터를 쉽게 개발할 수 있도록ActionFilterAttribute 라는 기본 클래스도 제공하고 있습니다. 이 클래스는Filter클래스를 상속하며 IActionFilter와 IResultFilter인터페이스를 구현하고 있습니다.
사실, 여기서 액션 필터라는 용어의 의미는 일관적이지 않은 편입니다. 기술적으로 말하자면, 액션 필터와 결과 필터 모두가 ActionFilterAttribute 클래스를 상속하기에, 결과 필터도 액션 필터의 일종인 것으로 볼 수 있기 때문입니다. 그렇기에, 액션 필터라는 용어는 광범위한 의미에서 ASP.NET MVC 프레임워크의 모든 필터를 지칭하는데 사용되는 편입니다.
기본 클래스인 ActionFilterAttribute 클래스는 오버라이드가 가능한 다음의 메서드를 갖고 있습니다.
- OnActionExecuting - 컨트롤러 액션이 실행되기 전에 호출됩니다.
- OnActionExecuted - 컨트롤러 액션이 실행된 후에 호출됩니다.
- OnResultExecuting - 컨트롤러의 액션결과가 실행되기 전에 호출됩니다.
- OnResultExecuted - 컨트롤러의 액션결과가 실행된 후에 호출됩니다.
다음 컬럼에서는 위의 메서드를 어떻게 구현하는지 알아볼 예정입니다.
Log 액션필터 만들기
이번 컬럼에서는 사용자 액션필터를 어떻게 생성하는지 보여주기 위해, 액션이 처리되는 상황을 기록하는 액션 필터를 작성해 볼까 합니다. LogActionFilter라는 사용자 정의 액션필터를 만들어서 액션이 실행되는 상태를 비주얼 스튜디오의 Output 창에 출력하도록 하겠습니다.
목록 2 - ActionFilters\LogActionFilter.cs
using System;
using System.Diagnostics;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1.ActionFilters
{
public class LogActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
Log("OnResultExecuting", filterContext.RouteData);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
Log("OnResultExecuted", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
}
목록 2에서 , OnActionExecuting(), OnActionExecuted(), OnResultExecuting(), OnResultExecuted() 메서드는 모두 Log() 메서드를 호출하고 있습니다. 메서드 이름과 현재의 라우트 데이터를Log() 메서드로 전달하고 있으며, Log() 메서드는 비주어 스튜디오의 Output 창에 그림 2에서와 같이 메세지를 출력합니다.

출처 : http://i1.asp.net/asp.net/images/mvc/14/Images/mvc_tutorial14_cs_figure02.png
목록 3에서는 HomeController 클래스가 어떻게 Log 액션 필터를 컨트롤러 클래스 전체에 적용하는 지를 보여주고 있습니다. Home 컨트롤러에 의해 노출된 모든 액션(이번 예제에서는 Index()와 About() 메서드가 해당됩니다)이 실행될 때마다 비주얼 스튜디오의 Output 창에 액션이 처리되는 상태를 출력됩니다.
목록 3 - Controllers\HomeController.cs
using System.Web.Mvc;
using MvcApplication1.ActionFilters;
namespace MvcApplication1.Controllers
{
[LogActionFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
}
요약
이번 컬럼에서는ASP.NET MVC 액션 필터를 소개하였습니다. 네 가지 종류의 필터 - 권한 필터, 액션 필터, 결과 필터, 예외 필터 - 에 대해 살펴보았으며, 기본 클래스인ActionFilterAttribute 클래스에 대해서도 간략하게 알아 보았습니다.
그리고, 강좌 후반부에서는 간단한 액션 필터를 구현하는 방법에 대해 다루었습니다. Log 액션 필터를 생성해서 액션이 처리되는 상황을 비주얼 스튜디오의 Output 창을 통해 확인해 보았습니다.