asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析
这篇文章我们开始看一下ActionFilter,从名字上其实就大概知道ActionFilter就是Action上的Filter,对吧,那么Action上的Filter大概有几个呢???
这个问题其实还是蛮简单的,因为我们听说Mvc本身就是一个扩展性极强的框架,自然就是层层有拦截,层层有过滤,对吧,比如我们看到的如下Controller类。
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
{
}
从这个父类的Controller中,我们就可以看到有5个Filter,如:IActionFilter,IAuthenticationFilter,IAuthorizationFilter,IExceptionFilter,IResultFilter,
对吧,首先我们还是从第一个ActionFilter说起。
一:IActionFilter解析
现在我们知道IActionFilter是一个接口,接下来感兴趣的就是这个ActionFilter里面到底是什么,比如我下面截图的这样。
//
// 摘要:
// Defines the methods that are used in an action filter.
public interface IActionFilter
{
//
// 摘要:
// Called after the action method executes.
//
// 参数:
// filterContext:
// The filter context.
void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要:
// Called before an action method executes.
//
// 参数:
// filterContext:
// The filter context.
void OnActionExecuting(ActionExecutingContext filterContext);
}
从上面这段代码中,我们可以看到其实这个接口里面只有两个方法,一个是OnActionExecuting,一个是OnActionExecuted,看这名字你应该就明白
其实就是在Action的前后分别执行,对吧,那这样的话,聪明的你就想到了应用场景,记录日志,获取action的访问量,以方便后续收费~~~ 接下来我
们来看看怎么来实现这两个方法。
1. 用override的方式实现ActionFilter
现在大家都知道Controller类已经实现了这个接口,那我们自己的XXXController刚好又继承了这个父Controller,所以面对这种情况,我们可以用
override来实现,比如下面我实现的这样。
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("hello"); base.OnActionExecuting(filterContext);
} protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("world"); base.OnActionExecuted(filterContext);
}
}
就这样我们就轻松加愉快的实现了,是不是很简单,但是仔细一想,这样的方法还是有一点限制的,也就是说我们override的依赖性太强了,比如说只有
class extends IActionFilter才可以,接下来我们再看有没有更灵活的方法来实现。
2. 自定义class extends IActionFilter
要想做到高度的灵活性,我们必须将这个实现类做成一个“原子单位”,有了这个原子单位,我们就可以很方便的将这个不可拆解的原子性应用到各个地方
去,对吧,这个原子在C#中可以用Attribute来实现,比如下面这样:
public class MyActionFilterAttribute : Attribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("hello");
} public void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("world");
}
}
ok,现在我们已经得到了一个原子性质的MyActionFilterAttribute特性,接下来我们可以将这个MyActionFilterAttribute应用到任何地方,如下图:
public class HomeController : Controller
{
[MyActionFilter]
public ActionResult Index()
{
return View();
}
}
3. ActionFilterAttribute
除了我们实现以下Attribute特性和IActionFilter接口,我们还可以继承一个mvc框架提供给我们的ActionFilterAttribute特性,迫不及待的看一下吧~
//
// 摘要:
// Represents the base class for filter attributes.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
//
// 摘要:
// Initializes a new instance of the System.Web.Mvc.ActionFilterAttribute class.
protected ActionFilterAttribute(); //
// 摘要:
// Called by the ASP.NET MVC framework after the action method executes.
//
// 参数:
// filterContext:
// The filter context.
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要:
// Called by the ASP.NET MVC framework before the action method executes.
//
// 参数:
// filterContext:
// The filter context.
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
//
// 摘要:
// Called by the ASP.NET MVC framework after the action result executes.
//
// 参数:
// filterContext:
// The filter context.
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
//
// 摘要:
// Called by the ASP.NET MVC framework before the action result executes.
//
// 参数:
// filterContext:
// The filter context.
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
}
从这个Attribute中可以看到,它整合了IActionFilter, IResultFilter,自然就有了这两个接口的方法,好了,不多说,我们来实现一下这个抽象类吧。
namespace WebApplication2.Controllers
{
public class HomeController : Controller
{
[MyActionFilter]
public ActionResult Index()
{
return View();
}
} public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
} public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}
}
}
二:源码分析
最好的源码分析方法,肯定是希望你下载一个reflector插件,这样我们就可以获取到运行时的可调试代码以及可以看到的调用堆栈,尤其是”调用堆
栈“,对你来说非常的重要。
1. 首先我们下一个断点在 OnActionExecuting方法里面,如下图:
2. 通过调用堆栈回退到上一个堆栈,如图:
这个方法其实非常的有意思,从方法名称中可以看到,其实它是一个递归的模式,也就是”OnActionExecuting" =>"进栈执行BeginInvokeActionMethod”
=>"退栈执行OnActionExecuted“方法,因为有一个非常好看的statement,比如:
Func<ActionExecutedContext> continuation = this.InvokeActionMethodFilterAsynchronouslyRecursive(num);
好了,更多的细节等待你去考究,希望本篇文章对您有帮助~~~
asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析的更多相关文章
- asp.net mvc 之旅—— 第三站 路由模板中强大的自定义IRouteConstraint约束
我们在写mvc的时候,经常会配置各种url模板,比如controller,action,id 组合模式,其实呢,我们还可以对这三个参数进行单独的配置,采用的方式自然 就是MapRoute中的const ...
- asp.net mvc 之旅 —— 第五站 从源码中分析asp.net mvc 中的TempData
在mvc的controller中,我们知道有很多的临时变量存放数据,比如说viewData,viewBag,还有一个比较特殊的tempData,关于前两个或许大家都明白, 基本上是一个东西,就是各自的 ...
- asp.net mvc 之旅—— 第四站 学会用Reflector调试我们的MVC框架代码
我们知道,现在能调试.net程序通常有两个,第一个是ILSpy,还是一个是Reflector,这两个小反编译软件算是我们研究底层代码中所拥有的一把 锋利小尖刀~~~,比如你看到的ILSpy这样的界面图 ...
- Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析
上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...
- 第六篇:Spark SQL Catalyst源码分析之Physical Plan
/** Spark SQL源码分析系列文章*/ 前面几篇文章主要介绍的是spark sql包里的的spark sql执行流程,以及Catalyst包内的SqlParser,Analyzer和Optim ...
- concurrent(六)同步辅助器CyclicBarrier & 源码分析
参考文档:Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例:https://www.cnblogs.com/skywang12345/p/3533995.html简介Cy ...
- Asp.net mvc 知多少(六)
本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...
- ASP.NET MVC 4源码分析之如何定位控制器
利用少有的空余时间,详细的浏览了下ASP.NET MVC 4的源代码.照着之前的步伐继续前进(虽然博客园已经存在很多大牛对MVC源码分析的博客,但是从个人出发,还是希望自己能够摸索出这些).首先有一个 ...
- ASP.NET WebForm / MVC 源码分析
浏览器 Url:https//localhost:6565/Home/Index ,https//localhost:6565/WebForm1.aspx,请求服务器(构建请求报文,并且将请求报文发送 ...
随机推荐
- 关于JavaScript中的delete操作
关于JavaScript中的delete操作 看到一道题,是这样的: (function(x){ delete x; return x; })(1); 1 null undefined Error 我 ...
- 我的架构设计~用层关系图说说mvc,mvvm,soa,ddd
下面是按着我所接触的架构模式,开始一个一个的说一下 第一 标准架构 三层结构
- jQuery? 回归JavaScript原生API
如今技术日新月异,各类框架库也是层次不穷.即便当年漫山红遍的JQuery(让开发者write less, do more,So Perfect!!)如今也有被替代的大势.但JS原生API写法依旧:并且 ...
- 阿里云 SDK python3支持
最近的一个项目需要操作阿里云的RDS,项目使用python3,让人惊讶的是官方的SDK竟然只支持python2 在阿里云现有SDK上改了改,文件的修改只涉及aliyun/api/base.py,详见h ...
- WCF学习之旅—WCF服务部署到IIS7.5(九)
上接 WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...
- 【Win 10 应用开发】透视效果
所谓透视效果,就是在平面坐标空间上模拟出“好像”三维的效果.要是老周没有记错的话,以前在写WP8相关的内容时写过,UWP中的透视方法也保留了以前的Do法,其实这玩意儿是从 Silverlight 沿袭 ...
- 【Win 10 应用开发】共享目标(UWP)
在开始吹牛之前,先给大伙伴们拜个年,祝各位身体健康.生活愉快.[码]到功成. ------------------------------------------------------------- ...
- ITTC数据挖掘平台介绍(七)强化的数据库, 虚拟化,脚本编辑器
一. 前言 好久没有更新博客了,最近一直在忙着找工作,目前差不多尘埃落定.特别期待而且准备的都很少能成功,反而是没怎么在意的最终反而能拿到,真是神一样的人生. 言归正传,一直以来,数据挖掘系统的数据类 ...
- 设计模式(五): 简单而又不失其重要性的单例模式(Singleton Pattern)
上篇博客我们系统的介绍了三种工厂模式,今天我们就来介绍一下单例模式.单例模式虽然简单,但是还是比较重要的,是常用设计模式之一.在之前的博客<Objective-C中的单例模式>中介绍了Ob ...
- 浅析JavaScript事件流——冒泡
一.什么是事件冒泡流 我们知道事件流指的是从页面中接受事件的顺序. 为了形象理解事件冒泡,可以想象三军主将诸葛亮,在帐内运筹帷幄,眼观六路耳听八方,这时候前方的战事情况就需要靠传令兵来传达,当第一位传 ...