mvc源码解读(12)-mvc四大过滤器之ActionFilter
2013-02-26 11:44
375 查看
上一篇中我们随便聊了聊MVC的授权过滤器AuthorizeFilter,其实真正关于.net平台下的认证体系之复杂远远超出了我们的想像,对权限的控制我们只能找到相对安全的做法,并不能从绝对上杜绝不安全的验证,特别是对于.net下授权权限的控制。有机会我们可以回过头来深入的探讨有关.net平台下的权限控制体系。这一篇我们继续根据mvc3的源码来学习mvc的ActionFilter方法过滤器。
和AuthorizeFilter原理一样,所有要用在Action方法上的方法过滤器特性都必须继承抽象类ActionFilterAttribute,该类是实现了不仅实现了接口FilterAttribute,还是实现了接口IActionFilter, IResultFilter,接口IActionFilter的成员如下:
OnActionExecuting在特性标注的方法执行之前执行的方法,同理OnActionExecuted是在特性标注的方法后执行的方法。接口IResultFilter我们等到下章来介绍。OnActionExecuting和OnActionExecuted接收ActionExecutingContext类实例作为参数,ActionExecutingContext类的成员如下:
看到这些成员我们该笑了,ActionDescriptor属性我们前面已经介绍过了,通过这个属性我们可以获取执行的ActionName和ControllerDescriptor,进而得到Controller的一切信息。ActionParameters获取Action方法执行的参数。ActionExecutingContext类继承自类ControllerContext,该类有以下几个重要的成员如下:
这里面我们需要注意的是HttpContext和RequestContext这两个属性。一个是封住了有关HTTP请求的信息,一个是封装了HttpContext和RouteData的请求上下文。看了那么多的微软定义的成员,我们来一个demo来演示ActionFilter的流程。
1:新建一个mvc3的应用程序,并创建一个控制器:
两个Action对应的视图如下:
紧接着我们创建一个自定义的方法过滤器MyTestActionFiter,该类继承自ActionFilterAttribute,具体如下:
打开F12,我们请求的是如下所示:
相应标头的信息如下:
我们可以知道我们请求Index方法的时候,由于我们在OnActionExecuting方法中将请求重定向(HTTP状态码:302)到了TestIndex方法,由此可以证明OnActionExecuting是在Action方法之前执行。我们再来看一个demo。我们将MyTestActionFilter的方法改进一下:
同时将MyActionFilter控制器改成如下:
按F5运行,运行结果如下:
看到这里,大家应该对ActionFiter的执行顺序应该有个大概的了解了吧:OnActionExecuting>Action>OnActionExecuted。但是有一点需要注意:ActionFiter都是在ViewResult执行之前执行,这也是为什么我在MyActionFilter中是直接输出内容,而不是返回ViewResult的原因,关于这一点,我们下一章结合ResultFilter做一个详细的解说。
和AuthorizeFilter原理一样,所有要用在Action方法上的方法过滤器特性都必须继承抽象类ActionFilterAttribute,该类是实现了不仅实现了接口FilterAttribute,还是实现了接口IActionFilter, IResultFilter,接口IActionFilter的成员如下:
public interface IActionFilter { void OnActionExecuting(ActionExecutingContext filterContext); void OnActionExecuted(ActionExecutedContext filterContext); } |
public virtual ActionDescriptor ActionDescriptor {get; set;} public virtual IDictionary<string, object> ActionParameters {get; set; } public ActionResult Result {get;set;} |
public virtual ControllerBase Controller {get; set; } public virtual HttpContextBase HttpContext { get {if (_httpContext == null) {_httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext(); } return _httpContext;} set {_httpContext = value;}} public virtual RouteData RouteData { get { if (_routeData == null) { _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData(); } return _routeData;} set { _routeData = value;} } public RequestContext RequestContext { get {if (_requestContext == null) { HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext(); RouteData routeData = RouteData ?? new RouteData(); _requestContext = new RequestContext(httpContext, routeData); } return _requestContext;} set {_requestContext = value;} |
1:新建一个mvc3的应用程序,并创建一个控制器:
public class MyActionFilterController : Controller { [MyTestActionFiter] public ActionResult Index(){return View();} public ActionResult TestIndex(){return View();}} |
@{Layout = null; } <!DOCTYPE html> <html> <head><title>Index</title></head><body><div><p>这里是测试的第一个页面--Index</p> </div> </body> </html> |
@{Layout = null; } <!DOCTYPE html> <html> <head><title>TestIndex</title></head><body><div><p>这里是测试的第二个页面--TestIndex</p> </div> /body></html> |
public class MyTestActionFiter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { //在动作请求之前执行的方法。 filterContext.Result = new RedirectResult("/MyActionFilter/TestIndex"); base.OnActionExecuting(filterContext); } } |
相应标头的信息如下:
我们可以知道我们请求Index方法的时候,由于我们在OnActionExecuting方法中将请求重定向(HTTP状态码:302)到了TestIndex方法,由此可以证明OnActionExecuting是在Action方法之前执行。我们再来看一个demo。我们将MyTestActionFilter的方法改进一下:
public override void OnActionExecuting(ActionExecutingContext filterContext) { //在动作请求之前执行的方法。 //filterContext.Result = new RedirectResult("/MyActionFilter/TestIndex"); filterContext.HttpContext.Response.Write("这是方法执行前的操作<br/>"); base.OnActionExecuting(filterContext); } public override void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write("这是方法执行之后的操作"); base.OnActionExecuted(filterContext); } |
public class MyActionFilterController : Controller { [MyTestActionFiter] public void Index() {Response.Write("这里是测试的第一个页面--Index<br/>"); } } |
看到这里,大家应该对ActionFiter的执行顺序应该有个大概的了解了吧:OnActionExecuting>Action>OnActionExecuted。但是有一点需要注意:ActionFiter都是在ViewResult执行之前执行,这也是为什么我在MyActionFilter中是直接输出内容,而不是返回ViewResult的原因,关于这一点,我们下一章结合ResultFilter做一个详细的解说。
相关文章推荐
- mvc源码解读(14)-mvc四大过滤器之ExceptionFilter
- mvc源码解读(11)-mvc四大过滤器之AuthorizationFilter
- mvc源码解读(13)-MVC四大过滤器之ResultFilter
- MVC中使用ActionFilterAttribute全局过滤器出现:网页无法正常运作 将您重定向的次数过多。解决办法
- MVC之 自定义过滤器(ActionFilterAttribute)
- ASP.NET MVC使用ActionFilterAttribute实现权限限制的方法(附demo源码下载)
- MVC源码分析 - Action/Result 过滤器执行时机
- mvc源码解读(9)-ActionDescriptor方法Action的描述对象
- MVC 过滤器 ActionFilterAttribute
- MVC源码分析 - Action查找和过滤器的执行时机
- MVC源码分析 - Action/Result 过滤器(续)
- mvc源码解读(10)-ParameterDescriptor方法Action方法的参数描述对象
- MVC源码分析 - Error过滤器
- ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
- asp.net MVC之 自定义过滤器(Filter)
- struct2源码解读(10)之执行action请求前篇
- asp.net mvc源码分析-Action篇 Action的执行
- rails源码解读之ActionView之画面标签
- asp.net mvc 1.0(5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test(非原创)
- ASP.NET MVC 入门8 Action Filter 与 内置的Filter实现(介绍)