zoukankan      html  css  js  c++  java
  • ASP.NET MVC 4.0的Action Filter

    有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你自定义创建action过滤器。Action过滤器是自定义的Attributes,用来标记添加Action方法之前或者Action方法之后的行为到控制器类中的Action方法中。

    什么情况下可能会用到action过滤的地方

    • 日志,异常处理
    • 身份验证和授权 - 限制用户的访问
    • 输出缓存 - 保存一个Action的结果
    • 网络爬虫的过滤
    • 本地化
    • 动态Action - 将一个Action注入到控制器中

    ASP.NET MVC 4.0 Framework支持四种不同类型的Filter

    1. Authorization filters – 实现IAuthorizationFilter接口的属性.
    2. Action filters – 实现IActionFilter接口的属性.
    3. Result filters – 实现IResultFilter接口的属性.
    4. Exception filters – 实现IExceptionFilter接口的属性.

    ASP.NET 内置的Filter默认的执行顺序按上面的列表中顺序进行。如验证(authorization)Filter永远都是最开始执行的,异常(exception)Filter永远都是最后执行的,当然你也可以根据需要通过Order属性设定过滤器执行的顺序。

    Action过滤器的执行顺序

    每一个Action过滤器都有一个 Order 属性,用来决定Action过滤器在该范围内的执行顺序。Order属性必需是0(默认值)或者更大的整数值。省略Order属性则会给该过滤器的Order值为 -1, 表明为指明顺序。任何一个在同一范围的Action过滤器Order设为 -1 的都将按不确定的顺序执行,单在此之前过滤器有一个特定的顺序(注:下面会说到).

    当设置Order属性的值的时候,必需指定一个唯一的值。如果两个或者更多的Action过滤器具有相同的Order属性值,将会抛出一个异常。

    1 [Filter1(Order = 2)]
    2 [Filter2(Order = 3)]
    3 [Filter3(Order = 1)]
    4 public ActionResult Index()
    5 {
    6    return View();
    7 }

    Filter的执行顺序为:Filter3 => Filter1 => Filter2.

    用户自定义ActionFilter

    为了让用户更简单的创建一个自定义action filter,ASP.NET MVC 4.0 Framework提供了一个基类ActionFilterAttribute,这个类实现了IActionFilter和IResultFilter接口,并且继承了Filter类。

    这里的术语并不完全一致,从技术上说,这个类继承ActionFitlerAttribute,并且同时实现了action filter和result filter接口,但是从宽松意义上说,在ASP.NET MVC Framework中,任何实现filter的类型都是action filter。

    ActionFilterAttribute类有以下的方法可以重写:

    • OnActionExecuting – 在controller action执行之前调用
    • OnActionExecuted – 在controller action执行之后调用
    • OnResultExecuting – 在controller action result执行之前调用
    • OnResultExecuted – 在controller action result执行之后调用

    以下是这几个方法的执行顺序:

    OnActionExecuting()-> Action execute & return View() ->OnActionExecuted() ->OnResultExecuting() -> Render View() ->OnResultExecuted()

    举个例子:检查登录是否为管理员身份

     1     public class AdminFilter : ActionFilterAttribute //自定义AdminFilter继承ActionFilterAttritube
     2     {
     3         public override void OnActionExecuting(ActionExecutingContext filterContext)
     4         {
     5             if (!Convert.ToBoolean(filterContext.HttpContext.Session["IsAdmin"]))
     6             {
     7                 //如果不是管理员,提示如下content
     8                 filterContext.Result = new ContentResult()
     9                 {
    10                     Content = "Unauthorized to access specified resource."
    11                 };
    12             }
    13         }
    14     }
    1         //引用自定义过滤器
    2         [AdminFilter]
    3         public ActionResult AddNew()
    4         {
    5             CreateEmployeeViewModel cvm = new CreateEmployeeViewModel();
    6             return View("CreateEmployee",cvm);
    7         }

    用户自定义带参数ActionFilter

     1     public class AdminFilter : ActionFilterAttribute
     2     {
     3         public string Message { get; set; } //增加message属性
     4         public override void OnActionExecuting(ActionExecutingContext filterContext)
     5         {
     6             if (!Convert.ToBoolean(filterContext.HttpContext.Session["IsAdmin"]))
     7             {
     8                 //直接提示content内容,不会执行action
     9                 filterContext.Result = new ContentResult()
    10                 {
    11                     //action调用过滤器时,得到message值
    12                     Content = Message + "Unauthorized to access specified resource."
    13                 };
    14             }
    15         }
    16     }        
     1         [AdminFilter(Message = "GetAddNewLink")] //传入message参数
     2         public ActionResult GetAddNewLink()
     3         {
     4             if(Convert.ToBoolean(Session["IsAdmin"]))
     5             {
     6                 return PartialView("AddNewLink");
     7             }
     8             else
     9             {
    10                 return new EmptyResult();
    11             }
    12             
    13         }

    自定义过滤器加入到全局过滤器

    有时我们想有些公共的方法需要每个Action都执行,但是又不想再每一个Controller上都打上Action标签,怎么办?幸好Asp.Net 从MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的AdminFilter注册到全局Filter中。

    App_Start /FilterConfig.cs

    1     public class FilterConfig
    2     {
    3         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    4         {
    5             filters.Add(new HandleErrorAttribute());
    6             filters.Add(new AdminFilter() { Message = "global" });
    7         }
    8     }

    补充说明:

    如果标签打到Controller上的话,AdminFilter将作用到Controller下的所有的Action。

      1.默认情况下Action上打了某个自定义标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。
      2.如果Action没有打上该标签,那么Controller上的标签便会被执行。

    如果想让Action上的标签执行一次,然后Controller上的标签也执行一次,那么应该如何操作呢?

       我们只需在FilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action。代码如下:

    1     [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    2     public class AdminFilter : ActionFilterAttribute
    3     {
    4 ........
    5     }
  • 相关阅读:
    Asp.Net Core 进阶(一) —— 读取appsettings.json
    chrome控制台模拟hover、focus、active等状态,方便调试
    windows server 注意windows的temp目录
    (转)大公司里怎样开发和部署前端代码?
    排序算法——二分插入排序
    排序算法——归并排序
    排序算法——冒泡排序
    排序算法——插入排序
    排序算法——快速排序
    linux安装和配置 mysql、redis 过程中遇到的问题记录
  • 原文地址:https://www.cnblogs.com/nx520zj/p/5666177.html
Copyright © 2011-2022 走看看