ASP.NET - MVC - Filters
ASP.NET MVC- Filters
Trong ASP.NET MVC, một yêu cầu 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ó trường hợp bạn muốn thực thi một số logic trước hoặc sau khi phương thức hành động thực thi. ASP.NET MVC cung cấp các 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 phương thức hành động thực thi. Các bộ lọc có thể được áp dụng cho một phương thức hành động hoặc bộ điều khiển theo cách khai báo hoặc lập trình. Khai báo có nghĩa là bằng cách áp dụng một thuộc tính bộ lọc cho một phương thức hành động hoặc lớp trình điều khiển và lập trình bằng cách thực hiện một giao diện tương ứng.kế thừa
MVC cung cấp các loại bộ lọc khác nhau. Bảng sau liệt kê các loại bộ lọc, bộ lọc tích hợp cho từng loại và giao diện phải được kế thừa để tạo lớp bộ lọc tùy chỉnh.
Loại Filter | Mô tả | Built-in Filter | Giao diện |
---|---|---|---|
Authorization filters | Thực hiện xác thực và ủy quyền trước khi thực hiện phương thức hành động. | [Authorize], [RequireHttps] | IAuthorizationFilter |
Action filters | Thực hiện một số thao tác trước và sau khi phương thức hành động thực thi. | IActionFilter | |
Result filters | Thực hiện một số thao tác trước hoặc sau khi thực hiện kết quả. | [OutputCache] | IResultFilter |
Exception filters | Thực hiện một số thao tác nếu có một ngoại lệ chưa được xử lý. | [HandleError] | IExceptionFilter |
Để hiểu chi tiết về filter, hãy lấy một ví dụ về Exception filter.
exception filter thực thi khi có một lỗi ngoại lệ chưa được xử lý xảy ra trong ứng dụng của bạn. Lớp HandleErrorAttribution ([HandlerError]) là lớp exception filter tích hợp trong framework MVC. Lớp HandErrorAttribution tích hợp này hiển thị Error.cshtml chứa trong thư mục mặc định Shared, khi xảy ra lỗi ngoại lệ chưa xử lý.
Error.cshtml
Ví dụ: Authorization Filter
[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();
}
}
Trong ví dụ trên, chúng ta đã sử dụng thuộc tính [HandleError] cho HomeController. Vì vậy, bây giờ nó sẽ hiển thị trang Error nếu bất kỳ phương thức hành động nào của HomeControllersẽ ném lỗi ngoại lệ chưa xử lý. Xin lưu ý rằng lỗi ngoại lệ chưa được xử lý là một lỗi ngoại lệ không được xử lý bởi khối try-catch .
Filters áp dụng cho controller sẽ tự động áp dụng cho các phương thức hành của controller.
CustomError được bật trong phần System.web của web.config,
Ví dụ: SetCustomError trong 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 ta ném lỗi ngoại lệ trong phương thức hành động Index.
Do đó, thuộc tính HandleError sẽ hiển thị trang lỗi chung cho bất kỳ lỗi ngoại lệ chưa xử lý nào xảy ra trong HomeController.
Register Filters
Filters có thể áp dụng ba mức.
1. Global Level
Bạn có thể áp dụng các bộ lọc ở 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 bộ lọc mặc định FilterConfig.RegisterGlobalFilters (). Global filters sẽ được áp dụng cho tất cả cáccontroller và phương thức hành động của một ứng dụng.
Bộ lọc [HandleError] được áp dụng toàn cục mặc định trong Ứng dụng MVC trong mọi ứng dụng MVC được tạo bằng Visual Studio như dưới đây.
Ví dụ: Register Global Filters
// 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());
}
}
2. Controller level
Filters cũng có thể áp dụng cho lớp controller. Vì vậy, các bộ lọc sẽ được áp dụng cho tất cả các phương thức hành động của lớp Controller nếu nó được áp dụng cho một lớp Controller.
Ví dụ: Action Filters trong Controller
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
3. Action method level
Bạn cũng có thể áp dụng các bộ lọc cho một phương thức hành động riêng lẻ. Vì vậy, bộ lọc sẽ chỉ được áp dụng cho phương thức hành động cụ thể đó.
Ví dụ: Filters trong Action Method
public class HomeController : Controller
{
[HandleError]
public ActionResult Index()
{
return View();
}
}
Cùng một cách, bạn có thể áp dụng nhiều bộ lọc tùy chỉnh hoặc tích hợp trên toàn cục hoặc ở cấp độ bộ điều khiển hoặc phương thức hành động cho các mục đích khác nhau, chẳng hạn như [Authorize], [RequireHttps], [ChildActionOnly], [OutputCache], [HandleError].
Filter Order
Như đã đề cập ở trên, MVC có nhiều loại bộ lọc khác nhau và nhiều bộ lọc có thể được áp dụng cho một lớp controller hoặc phương thức hành động. Vì vậy, các bộ lọc chạy theo thứ tự sau đây.
- Authorization filters
- Action filters
- Response filters
- Exception filters
Tạo Filter tùy chỉnh
Bạn có thể tạo các thuộc tính bộ lọc tùy chỉnh bằng cách kế thừa giao diện bộ lọc phù hợp mà bạn muốn tạo bộ lọc tùy chỉnh và cũng lấy ra một lớp FilterAttribution để bạn có thể sử dụng lớp đó làm thuộc tính.
Ví dụ: kế thừa lớp IExceptionFilter và FilterAttribution để tạo bộ lọc ngoại lệ tùy chỉnh. Theo cách tương tự, kế thừa giao diện IAuthorizatinFilter và lớp FilterAttribution để tạo bộ lọc ủy quyền tùy chỉnh.
Ví dụ: Custom Exception Filter
class MyErrorHandler : FilterAttribute, IExceptionFilter
{
public override void IExceptionFilter.OnException(ExceptionContext filterContext)
{
Log(filterContext.Exception);
base.OnException(filterContext);
}
private void Log(Exception exception)
{
//log exception here..
}
}
Ngoài ra, bạn cũng có thể lấy được một lớp bộ lọc tích hợp và ghi đè một phương thức thích hợp để mở rộng chức năng của các bộ lọc tích hợp.
Let's create custom exception filter to log every unhandled exception by deriving built-in HandleErrorAttribute class and overriding OnException method as shown below.
Ví dụ: Custom Exception Filter
class MyErrorHandler : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
Log(filterContext.Exception);
base.OnException(filterContext);
}
private void Log(Exception exception)
{
//log exception here..
}
}
Bây giờ, bạn có thể áp dụng thuộc tính MyErrorHandler ở cấp độ toàn cục hoặc controller hoặc phương thức hành động, giống như cách chúng ta đã áp dụng thuộc tính HandleError.
Ví dụ: Custom Action Filters cho Controller
[MyErrorHandler]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}