Filter trong ASP.NET MVC

Trong ASP.NET MVC, một yêu cầu của người dùng được chuyển đến controller và phương thức hành động thích hợp. Tuy nhiên, có thể có những trường hợp bạn muốn thực thi một số logic trước hoặc sau khi một phương thức hành động thực thi. ASP.NET MVC cung cấp các filter (bộ lọc) cho mục đích này.

ASP.NET MVC Filter là một lớp tùy chỉnh, nơi bạn có thể viết logic tùy chỉnh để thực thi trước hoặc sau khi một phương thức hành động thực thi. Filter có thể được áp dụng cho một phương thức hành động hoặc controller theo cách khai báo hoặc theo cách lập trình.

Khai báo có nghĩa là bằng cách áp dụng một filter attribute cho một phương thức hành động hoặc lớp controller và lập trình bằng cách triển khai một interface tương ứng.

ASP.NET MVC cung cấp các loại filter khác nhau. Bảng sau liệt kê các loại filter, filter tích hợp và interface phải được triển khai để tạo filter tùy chỉnh.

Loại filter Mô tả Filter tích hợp Interface
Authorization filter Thực hiện xác thực và ủy quyền trước khi thực hiện một phương thức hành động. [Authorize], [RequireHttps] IAuthorizationFilter
Action filter Thực hiện một số thao tác trước và sau khi một phương thức hành động thực thi. IActionFilter
Result filter Thực hiện một số thao tác trước hoặc sau khi thực thi kết quả trả về của phương thức hành động. [OutputCache] IResultFilter
Exception filter Thực hiện một số thao tác nếu có một ngoại lệ chưa xử lý được ném ra trong quá trình thực thi đường ống ASP.NET MVC. [HandleError] IExceptionFilter

Để hiểu chi tiết về filter, chúng ta hãy lấy một ví dụ về Exception filter được tích hợp sẵn. Exception filter thực thi khi một ngoại lệ chưa được xử lý xảy ra trong ứng dụng của bạn. Attribute HandleErrorAttribute là một lớp exception filter được tích hợp sẵn được sử dụng để hiển thị Error.cshtml theo mặc định khi một ngoại lệ unhandled xảy ra.

Filter trong ASP.NET MVC

Ví dụ sau minh họa việc sử dụng attribute [HandError] trên lớp controller.

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        //throw exception for demo
        throw new Exception("This is unhandled exception");
            
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }        
}

Ở ví dụ trên, attribute [HandleError] được áp dụng cho lớp HomeController. Vì vậy, một trang lỗi Error.cshtml sẽ được hiển thị nếu bất kỳ phương thức hành động nào của HomeController ném ra một ngoại lệ chưa được xử lý.

Xin lưu ý rằng các ngoại lệ không được xử lý là các ngoại lệ không được xử lý bởi các khối try-catch.

Các filter được áp dụng cho controller sẽ tự động được áp dụng cho tất cả các phương pháp hành động của controller.

Hãy đảm bảo rằng chế độ CustomError này được bật trong phần System.web của web.config.

<customErrors mode="On" /> 

Bây giờ, nếu bạn chạy ứng dụng, bạn sẽ nhận được trang lỗi sau vì chúng tôi đưa ra một ngoại lệ trong phương thức hành động Index() cho mục đích demo.

Filter trong ASP.NET MVC

Đăng ký filter

Filter (bộ lọc) có thể được áp dụng ở ba cấp độ.

Filter cấp độ toàn cục

Bạn có thể áp dụng filter ở cấp độ toàn cục trong sự kiện Application_Start của tệp global.asax.cs bằng cách sử dụng phương thức mặc định FilterConfig.RegisterGlobalFilters(). Các filter toàn cục sẽ được áp dụng cho tất cả các controller và phương thức hành động của một ứng dụng.

Filter [HandleError] được áp dụng toàn cục trong ứng dụng ASP.NET MVC theo mặc định trong mọi ứng dụng MVC được tạo bằng Visual Studio, như được hiển thị bên dưới.

// MvcApplication class contains in Global.asax.cs file 
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    }
}

// FilterConfig.cs located in App_Start folder 
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

Filter cấp độ controller

Filter cũng có thể được áp dụng cho lớp controller. Filter cấp độ controller được áp dụng cho tất cả các phương thức hành động. Filter dưới đây có thể áp dụng cho tất cả các phương thức hành động của lớp HomeController, nhưng không áp dụng cho các controller khác.

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }
}

Filter cấp độ phương thức hành động

Một hoặc nhiều filter cũng có thể được áp dụng cho một phương thức hành động riêng lẻ. Filter dưới đây chỉ áp dụng cho phương thức hành động Index().

public class HomeController : Controller
{
    [HandleError]
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }
}

Action Filter trong ASP.NET MVC

Action filter thực thi trước và sau khi một phương thức hành động thực thi. Attribute action filter có thể được áp dụng cho một phương thức hành động riêng lẻ hoặc cho một controller. Khi một action filter được áp dụng cho một controller, nó sẽ được áp dụng cho tất cả các phương thức hành động của controller.

Attribute OutputCache dưới đây là một attribute action filter tích hợp có thể được áp dụng cho một phương thức hành động mà chúng ta muốn lưu đầu ra vào bộ nhớ cache. Ví dụ: đầu ra của phương thức hành động sau sẽ được lưu vào bộ nhớ cache trong 100 giây.

[OutputCache(Duration=100)]
public ActionResult Index()
{
    return View();
}

Tạo action filter tùy chỉnh

Bạn có thể tạo action filter tùy chỉnh theo hai cách, thứ nhất, bằng cách triển khai interface IActionFilter và lớp FilterAttribute. Thứ hai, bằng cách kế thừa lớp trừu tượng ActionFilterAttribute.

Interface IActionFilter bao gồm các phương thức sau đây để triển khai:

  • void OnActionExecuted(ActionExecutedContext filterContext)
  • void OnActionExecuting(ActionExecutingContext filterContext)

Lớp trừu tượng ActionFilterAttribute bao gồm các phương thức sau để ghi đè:

  • void OnActionExecuted(ActionExecutedContext filterContext)
  • void OnActionExecuting(ActionExecutingContext filterContext)
  • void OnResultExecuted(ResultExecutedContext filterContext)
  • void OnResultExecuting(ResultExecutingContext filterContext)

Như bạn có thể thấy, lớp ActionFilterAttribute có bốn phương thức nạp chồng. Nó bao gồm các phương thức OnResultExecutedOnResultExecuting, có thể được sử dụng để thực thi logic tùy chỉnh trước hoặc sau khi kết quả thực thi. Action filter thường được sử dụng để ghi log, bộ nhớ đệm, ủy quyền, v.v.

Ví dụ sau minh họa việc tạo một lớp action filter tùy chỉnh để ghi log.

public class LogAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Log("OnActionExecuted", filterContext.RouteData); 
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Log("OnActionExecuting", filterContext.RouteData);      
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Log("OnResultExecuted", filterContext.RouteData);      
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Log("OnResultExecuting ", 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);
    }
}

Ở ví dụ trên, lớp Log kế thừa từ lớp ActionFilterAttribute. Nó ghi log trước và sau khi phương thức hành động hoặc kết quả thực thi. Bạn có thể áp dụng attribute Log cho bất kỳ controller hoặc một phương thức hành động nào mà bạn muốn ghi lại việc thực thi phương thức hành động.

[Log]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }
}

Ví dụ trên sẽ hiển thị kết quả sau khi truy cập url http://localhost:1234/home.

OnActionExecuting- controller: Home action: Index
OnActionExecuted- controller: Home action: Index
OnResultExecuting - controller: Home action: Index
OnResultExecuted- controller: Home action: Index

Bằng cách này, bạn có thể theo dõi việc thực thi các phương thức hành động bằng cách sử dụng các action filter.

ASP.NET MVC
Bài Viết Liên Quan:
Bundle và minify js, css trong ASP.NET MVC
Trung Nguyen 11/04/2021
Bundle và minify js, css trong ASP.NET MVC

Các kỹ thuật bundle (gộp file) và minify (rút gọn file) đã được giới thiệu trong ASP.NET MVC 4 để cải thiện thời gian tải trang.

ViewBag, ViewData và TempData trong ASP.NET MVC
Trung Nguyen 10/04/2021
ViewBag, ViewData và TempData trong ASP.NET MVC

Trong hướng dẫn này, bạn sẽ tìm hiểu ViewBag, ViewData và TempData là gì và cách sử dụng chúng trong ASP.NET MVC

Layout View trong ASP.NET MVC
Trung Nguyen 10/04/2021
Layout View trong ASP.NET MVC

Trong hướng dẫn này, bạn sẽ tìm hiểu về Layout View là gì các cách sử dụng Layout View trong ASP.NET MVC.

Validation trong ASP.NET MVC
Trung Nguyen 10/04/2021
Validation trong ASP.NET MVC

Ở bài viết này, bạn sẽ học cách triển khai xác thực dữ liệu và hiển thị thông báo lỗi xác thực dữ liệu trong ứng dụng ASP.NET MVC.