带你读开源—ASP.NET_MVC(二)

rufengit 2016-08-23 09:31:53
加精
上篇文章从整体上介绍了ASP.NET MVC的请求处理流程,大概分为“路由”、“控制器”、“视图”以及“模型”,下面便按照流程依次展开。
一、路由
提到路由,实际上分为ASP.NET的核心路由引擎和MVC路由。核心路由引擎是不开源的(微软留了一手),它负责解析浏览器端传来的URL,并为之分配控制器。
这里我们要分析的是MVC路由,即MvcRouteHandler,该类显式实现了IRouteHandler接口,它的GetHttpHandler方法返回了一个MvcHandler对象,而MvcHandler实现了IHttpHandler接口,所以它包含一个ProcessRequest方法,如下:

代码段1

这个ProcessRequest方法相信大家都会觉得脸熟吧?不错,我们在ASP.NET WebForm开发中,经常会用到一般处理程序,即.ashx文件,这个文件中的类就实现了IHttpHandler接口,也有一个ProcessRequest方法。
好了,这个ProcessRequest方法就是路由定位到控制器后,执行的核心操作。也就是说,controller.Execute(RequestContext)语句的执行,导致了HTML响应的生成及回送浏览器。简单吧?我们在这里只是提到了最核心、最骨架的部分,没有涉及细节,为的就是不让大家被细枝末节所干扰。接下来就该分析控制器了。
二、控制器
代码段1中的controller是接口IController的一个实例,而接口IController很简单,只有一个方法如下:
代码段2

Controller的实例化是由【ProcessRequestInit(httpContext, out controller, out factory)】这个语句完成的,下面我们看一下ProcessRequestInit这个方法中实例化Controller的部分,不考虑细节,直奔主题。

代码段3

代码段3中的【controller = factory.CreateController(RequestContext, controllerName)】语句,就是实例化控制器的地方,这里根据路由系统定位的控制器信息(即我们在Controller文件夹中定义的各个控制器类),利用反射创建控制器对象。当然,这里面还有很多实现细节,比如控制器工厂、请求验证等,为了保持脉络清晰,在此略过,下文再谈。
IController接口在MVC中有若干个内置的实现类,包括ControllerBase以及IAsyncController,而Controller是ControllerBase的子类,是我们最常用的控制器基类。
其实,我们完全可以自己实现IController,例如:

代码段4

怎么样?So Easy!完全可以不用什么高大上的Razor引擎之类的东东。但是这样做会导致极强的耦合,我们需要自己解析拼接HTML,这可是个累人的活儿。
我们还是看看MVC的Controller类是怎么实现的吧。Controller继承于ControllerBase类,ControllerBase实现了Execute方法(代码段5),而Controller重写了ControllerBase的ExecuteCore方法(代码段6)。

代码段5


代码段6

我们看一下ExecuteCore方法,其核心语句是【if (!ActionInvoker.InvokeAction(ControllerContext, actionName))】,这条语句就是执行某个具体Action的地方,该语句执行完后,HTTP响应就被发回了浏览器。这里用到了ActionInvoker.InvokeAction方法,其中的ActionInvoker是IActionInvoker接口的实例,该接口定义也相当简单,如下:

代码段7

MVC内置的IActionInvoker实现类有ControllerActionInvoker和IAsyncActionInvoker,后者是异步类,先不管它,这里我们重点分析一下ControllerActionInvoker。
ControllerActionInvoker的InvokeAction方法实现较为复杂,有大概90行代码。今天有点累了,明天继续。
...全文
4736 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
a13826148677 2018-01-15
  • 打赏
  • 举报
回复
没找到1
莫莫莫i 2016-09-08
  • 打赏
  • 举报
回复
看不懂 - -
昆吾kw 2016-08-28
  • 打赏
  • 举报
回复
感谢分享支持
insus 2016-08-26
  • 打赏
  • 举报
回复
关注,研究与学习中......
rufengit 2016-08-24
  • 打赏
  • 举报
回复
坚持每天发一篇,希望能坚持住……
  • 打赏
  • 举报
回复
感谢楼主的无私奉献
rufengit 2016-08-23
  • 打赏
  • 举报
回复
嗯,博客稍后更新,谢谢!
anythingBlank 2016-08-23
  • 打赏
  • 举报
回复
楼主可以写博客哦

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧