ASP.NET MVC中Filter使用

Filter 接口

Filter类型 接口 MVC的默认实现 Description
Authorization IAuthorizationFilter AuthorizeAttribute 最先执行,在其他类型的filter和action方法前执行
Action IActionFilter ActionFilterAttribute 在action方法执行前和执行后执行
Result IResultFilter ActionFilterAttribute 在result执行前和执行后执行
Exception IExceptionFilter HandleErrorAttribute 在抛出异常时执行,(异常发生在action/result/filter)
 
Authorization Filter
Authorization Filter是所有Filter类型中第一个执行的Filter,它在action方法调用前执行。Authorization Filter需要实现IAuthorizationFilter接口:
public interface IAuthorzationFilter
{
     void OnAuthorization(AuthorizationContext context);
}
可以看出,我们要实现Authorization机制的代码就需要放在OnAuthorization方法中,而其参数类型AuthorizationContext继承于ControllerContext,如下所示:
复制代码
 public class AuthorizationContext : ControllerContext
 {   

     public AuthorizationContext();   

     public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor);     
     public virtual ActionDescriptor ActionDescriptor { get; set; }
     public ActionResult Result { get; set; }

 }
复制代码
AuthorzationContext额外提供了Result属性和ActionDescriptor属性,result属性表示授权阶段呈现的ActionResult,而ActionDescriptor则包含了当前执行Action的信息。
Asp.net MVC给我们提供了一个IAuthorzationFilter的实现AuthorizeAttribute(没错,它是一个Attribute,继承于FilterAttribute),该Attribute可以应用于Controller和Action, 它包含Roles和Users属性,指定特定的角色和用户才可以授权使用。比如:
复制代码
public class HomeController : Controller
{
     [Authorize(Users = "zhang, zheng", Roles = "admin")]
     public ActionResult Index()
     {
          return View();
     }
}
复制代码
以上代码表示只有用户zhang,zheng并且拥有角色admin的用户才可以被授权执行Index Action。

 
         
Exception Filter
当一个未处理异常抛出时,Exception Filter将会被执行。Exception Filter需要实现IExceptionFilter接口:
public interface IExceptionFilter
{
     void OnException(ExceptionContext filerContext);
}
ExceptionContext同样继承于ControllerContext,它提供了以下额外的属性:
属性名 类型 描述
ActionDescriptor ActionDescriptor 提供当前所执行的Action的信息
Result ActionResult Exception Filter所呈现的ActionResult
Exception Exception 未处理的异常
ExceptionHandled bool 表示是否已有其他filter处理过此异常
 
        
ExceptionHandled是一个很重要的属性。一般来说,当一个Exception Filter执行时,我们首先需要检查ExceptionHandled属性,如果为true,则表示已有其他filter处理过此异常了,就不需要再次进行处理了,以免覆盖其他filter所解决的Exception。如果为false,则对该Exception进行相应的处理,处理之后将ExceptionHandled属性设置为true。默认的,如果没有Exception Filter将ExceptionHandled属性设置为true, ASP.NET MVC将使用默认的异常处理,即显示我们经常看到的异常页面。
Action Filter
Action Filter可以基于任何目的使用,它需要实现IActionFilter接口:
public interface IActionFilter
{
     void OnActionExecuting(ActionExecutingContext filterContext);
     void OnActionExecuted(ActionExecutedContext filterContext);
}
顾名思义,OnActionExecuting方法将在Action方法执行前调用,而OnActionExecuted方法将在Action方法执行后调用。
 
我们可以看到,OnActionExecuting方法的参数filterContext的类型为ActionExecutingContext,它同样继承于ControllerContext,并额外提供了Result属性和ActionDesciptor属性,它们的作用在上篇已经介绍过。
 
同样,OnActionExecuted方法的参数filterContext的类型为ActionExecutedContext,继承于ControllerContext,额外提供了Result属性,ActionDescriptor属性和Exception属性(Action方法抛出的未处理异常).
 
多说无益,来看一个例子吧:
复制代码
     public class CustomerActionAttribute : FilterAttribute, IActionFilter
     {
        private Stopwatch timer;

        public void OnActionExecuting( ActionExecutingContext filterContext)
        {
            timer = Stopwatch .StartNew();
        }
        public void OnActionExecuted( ActionExecutedContext filterContext)
        {
            timer.Stop();

            if (filterContext.Exception == null )
            {
                filterContext.HttpContext.Response.Write(
                        string .Format("<div>Action执行时间:{0}</div>" , timer.Elapsed.TotalSeconds));
            }
        }
    }
复制代码
复制代码
     public class HomeController : Controller
     {
        [CustomerAction]
        public ViewResult Index()
        {
            return View();
        }

    }
复制代码

执行结果:

Result Filter
Result Filter跟Action Filter有些类似,但它是在ActionResult执行前后执行,Result Filter需要实现IResultFilter接口:
public interface IResultFilter
{
     void OnResultExecuting(ResultExecutingContext filterContext);
     void OnResultExecuted(ResultExecutedContext filterContext);
}
 
ActionFilterAttribute
ASP.NET MVC提供了ActionFilterAttribute,它是一个抽象类,继承FilterAttribute,实现IActionFilter和IResultFilter接口:
复制代码
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
     public virtual void OnActionExecuting(ActionExecutingContext filterContext)
     {
     }

     public virtual void OnActionExecuted(ActionExecutedContext filterContext)
     {
     }

     public virtual void OnResultExecuting(ResultExecutingContext filterContext)
     {
     }

     public virtual void OnResultExecuted(ActionExecutingContext filterContext)
     {
     }
}
复制代码
感觉这个类,就是给我们提供方便的,让我们能根据需要重写相应的方法。
 
Global Filter 
如果我们需要将一个Filter作用于所有的Controller和Action的话,我们可以在FilterConfig.cs中的RegisterGlobalFilters方法注册全局Filter:
复制代码
   public class FilterConfig
    {
        public static void RegisterGlobalFilters( GlobalFilterCollection filters)
        {
            filters.Add( new HandleErrorAttribute ());
            filters.Add( new CustomerActionAttribute ());
        }
    }
复制代码

 

Filter 的执行顺序
总的来说(相同类型的Filter),Global Filter最先执行,随后执行的是作用于Controller的Filter,最后执行的是作用于Action的Filter。但是Exception Filter的执行顺序却是完全相反的。
如果是针对同一个Action或Controller的多个Filter(filer的类型相同),它们的执行顺序是未定的。但是我们可以通过指定Order属性来定义执行顺序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值