ASP.NET MVC学习笔记-MVC运行机制之源码剖析

asp.net mvc源码分析-RenderAction和RenderPartial 截止上篇文章asp.net mvc源码分析-ActionResult篇 RazorView.RenderView 相信大家对mvc的大致流程应该有所了解。现在我们来看看我们在mvc开发中用的最多的几个方法,我想排在第一的应该是Html.RenderAction和Html.RenderPartial吧。先说简单的吧:RenderPartial和Partial  public static void 阅读详情

 学习ASP.NET MVC已经有段时间了,以前都是断断续续的了解了下, 对于ASP.NET MVC路由及运行机制一直不是很了解, 在网络上找了好多资料无非都是讲解了下如何添加ASP.NET MVC路由及创建自定义视图引挚等. 因此最近这几天, 下载了ASP.NET MVC源码好好研究了一翻, 将其运行机制记录下来, 一来整理下自己的理解思路, 加强自己的理解, 二来也希望对学习ASP.NET的后来者有所帮助, 文中都是自我理解, 有错误之处望高手能帮忙纠正之!!

我们都知道ASP.NET首先是从Global.aspx中开始运行的, 在Application_Start()中添加路由映射后, 就由URLRouting组件创建IRouteHandler并执行, 在ASP.NET MVC默认情况下是MvcRouteHandler(关于自定义RouteHandler, 请参考其他的相关文章), 我们先看看MvcRouteHandler的源码:

 

从源码里我们可以看出,MvcRouteHandler返回了MvcHandler实例并传递RequestContext参数,  然后转到MvcHandler的ProcessRequest(HttpContext httpContext)方法中, 并在这个方法里根据httpContext创建了HttpContextWrapper(继承于HttpContextBase)实例, 源码如下:

 

Controller解析执行就是从这里开始的了,是ASP.NET MVC处理请求的关键部分, 我们现在逐条分析代码,根据执行顺序一步一步揭开它神秘的面纱, 首先看看ControllerBuilder类部分代码:

 

默认情况下ControllerBuilder.GetControllerFactory()是返回的DefaultControllerFactory实例,接着再往下看:
 IController controller = factory.CreateController(RequestContext, controllerName);
它是如何创建controller的呢? 看看的DefaultControllerFactory源码就知道了.

 

这里调用了GetControllerType()和GetControllerInstance()方法来创建controller,在GetControllerType方法中主要是一行代码:return GetControllerTypeWithinNamespaces(controllerName, null /* namespaces */);那我们也看看它做了些什么动作.

 

它主要是调用了ControllerTypeCache中的两个方法,在EnsureInitialized方法中调用了GetAllControllerTypes(BuildManager)方法从BuildManager中获取所有程序集中public, not abstract并且以"Controller"结尾的Type放入列表中进行缓存,ControllerTypeCache.GetControllerTypes(controllerName, namespaces)主要是从缓存的字典中读取对应的Controller.
接着在GetControllerInstance方法中调用Activator.CreateInstance静态方法创建Controller, 然后执行Controller的Execute方法,Execute方法是IController接口中定义的方法, ControllerBase类实现了此方法并提供了TempData和ViewData属性, Execute实现如下:

 

Initialize方法根据RequestContext创建了ControllerContext对象, ControllerContext有4个属性:
        public virtual ControllerBase Controller;                //初始化时传入
        public virtual HttpContextBase HttpContext;            //默认为RequestContext.HttpContext或EmptyHttpContext
        public RequestContext RequestContext ;                //初始化时传入
        public virtual RouteData RouteData;                //默认为RequestContext.RouteData
ExecuteCore()是ControllerBase的抽象方法,Controller类实现了此方法,实现如下:

 

在ExecuteCore()中实现了TempData的Load和Save, 所以TempData才可以在其他的View中有效,而ViewData只能在对应的View中有效. ActionInvoker是Controller中的属性, 其默认为ControllerActionInvoker实例, 我们接着再看看ActionInvoker.InvokeAction(ControllerContext, actionName)又是怎么找到Action的呢? 还是从源码入手:

 

GetControllerDescriptor(controllerContext)方法调用DescriptorCache.GetDescriptor()并返回了ReflectedControllerDescriptor(继承于ControllerDescriptor)实例,并在其Cache属性中保存了ReflectedControllerDescriptor实例. ReflectedControllerDescriptor类中有一个ActionMethodSelector类型的私用变量_selector, 在ActionMethodSelector构造方法中调用ControllerType.GetMethods方法得到了Controller中的所有方法并过滤出Action方法存储到AliasedMethods和NonAliasedMethods属性中, 用于查询Action.而FindAction(controllerContext, controllerDescriptor, actionName)最终也是调用了ControllerDescriptor中的FindAction(),而这里的ControllerDescriptor始终是ReflectedControllerDescriptor, 所以我们找到ReflectedControllerDescriptor的FindAction方法:

 

可以看出, 它是调用ActionMethodSelector的FindActionMethod然后构造新的ReflectActionDescriptor返回的,在ActionMethodSelector的FindActionMethod方法里就用到了刚才提到了AliasedMethods和NonAliasedMethods属性找出相匹配的方法, 再回到InvokeAction继续往下看执行的是GetFilters将controller添加到4个基本Filter列表中去:

 

FilterInfo类只有四个List属性, 分别是:
        public IList<IActionFilter> ActionFilters;
        public IList<IAuthorizationFilter> AuthorizationFilters;
        public IList<IExceptionFilter> ExceptionFilters;
        public IList<IResultFilter> ResultFilters;

再接着执行GetParameterValues(controllerContext, actionDescriptor), 在这个方法里获取Action参数并实现Model绑定,GetParameterValue代码如下:

 

接着由InvokeActionMethodWithFilters转到InvokeActionMethodFilter执行filter.OnActionExecuting(即controller),然后从InvokeActionMethodf中执行ActionDescriptor的抽象方法Execute()并创建ActionResult返回.
在Execute方法中会创建ActionMethodDispatcher对象, 在ActionMethodDispatcher构造函数中传入Aciton方法, 再调用ActionMethodDispatcher的Execute进入具体的Action方法(即Controller的Action方法), 现由Controller的View方法创建ViewResult对象返回:

 

到此Action执行结束, 执OnActionExecuted()方法,再回到InvokeAction执行InvokeActionResultWithFilters, 这时OnResultExecuting()就开始运行了,OnResultExecuting执行完了后, 就执行ActionResult.ExecuteResult, 从上面代码可以知道View方法返回的是ViewResult,ExecuteResult是在ActionResult类中定义的抽象方法, ViewResultBase实现了此方法查找ViewEngine及对View调用Render.

 

FindView是ViewResultBase中定义的抽象方法,在ViewResult中的实现如下:    

 

调用了ViewEngineCollection.FindView, ViewEngineCollection是ViewResultBase中的属性:

 

默认情况下是ViewEngines的静态属性Engines, 所以在自定义视图引挚时, 我们一般都会在Globol.cs中的Application_Start()中将自己定义的视图引挚添加到ViewEngines.Engines中去, ASP.NET MVC默认情况下就有new WebFormViewEngine().

 

WebFromViewEngine继承于VirtualPathProviderViewEngine, 而VirtualPathProviderViewEngine继承了IViewEngine, 并实现了IViewEngine的FindView,FindPartialView及ReleaseView, 还提供了MasterLocaltionFormats,PartialViewLocationFormats和ViewLocationFormats属性, 通常我们自定义的视图引挚可以继承于VirtualPathProviderViewEngine, ViewEngineCollection.FindView遍历所有的ViewEngine, 并调用ViewEngine.FindView根据返回的字符串数组创建ViewEngineResult对象返回, 默认情况下ViewEngineCollection只有一个ViewEngine(WebFromViewEngine), 所以我们找到VirtualPathProviderViewEngine的FindView实现:

 

GetPath根据ViewLocationFormats数据顺序查找到第一个符合条件的就返回, CreateView是VirtualPathProviderViewEngine提供的抽象函数, 需要在自定义的ViewEngine中实现, WebFormViewEngine实现如下:

 

ViewEngineResult类中只包含了三个属性:
        public IEnumerable<string> SearchedLocations;
        public IView View;
        public IViewEngine ViewEngine;

FindView后返回到ExecuteResult方法中执行View.Render方法并传入了ViewContext(ControllerContext, View, ViewData, TempData),在WebFormView.Render中创建ViewPage对象并输出,关键代码如下:

 

代码page.ViewData = context.ViewData就将Controller的ViewData传递到ViewPage中了, 因此我们可以在aspx页面使用Controller中的ViewData,TempData属性实质返回的是ViewPage中的ViewContext.TempData. 在ViewPage.RenderView对HtmlHelper,AjaxHelper和UrlHelper进行初始化后,就调用ProcessRequest开始进行页面处理,如OnPreInit, OnPreRender事件等, 最后再执OnResultExecuted,整个ASP.NET MVC调用流程到此就结束了.

【ASP.NET MVC4】第一课:初识ASP.NET MVC,创建第一个ASP.NET MVC项目 知识点:理解ASP.NET MVC 阅读详情

相关推荐

ASP.NET 3.5 MVC 入门:文章管理系统源码解析

本文还有配套的精品资源,点击获取 简介:本文分析了一个基于 ASP.NET 3.5 和 MVC 框架的文章管理系统的源码,涉及 MVC 模式、ASP.NET MVC 框架原理、路由配置、控制器设计、模型结构、视图实现、数据库交互、验证和错误处理等关键知识点。开发者通过深入理解这个系统的源码,能有效掌握 ASP.NET MVC 框架的应用,学会实现文章的增删改查、数据验证和 ...

weixin_32306683的博客 902

ASP.NET Core MVC 源码学习:MVC 启动流程详解

前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习。 ASP.NET Core 是新一代的 ASP.NET 应用程序,它是跨平台的,并且不依赖于 IIS,新的 MVC Core 设计加入了依赖注入和模块化的 Http 处理管道,这篇文章我们一起通过源码看一下它的启动过程,每一步都很重要...

weixin_34148456的博客 535

ASP.NET MVC 4与ASP.NET MVC 5深度比较及源码分析合集

ASP.NET MVC 是一个开源的网络应用程序框架,由微软开发,并构建在 .NET Framework 之上。它引入了模型-视图-控制器(MVC)设计模式,这种模式把应用程序分为三个主要的组件:模型(Model)、视图(View)和控制器(Controller),使应用程序更容易维护和扩展。MVC 模式最初于1979年提出,并在1990年代广泛应用于Smalltalk-80系统中。ASP.NET MVC 将这种模式带入了 Web 开发,促进了企业的应用开发。

weixin_35797963的博客 658

.Net MVC订单后台管理系统源码编码过程

Net MVC订单后台管理系统源码编码过程1. 实现语言:C#语言。2. 环境要求:Visual Studio 2012+SQL Server 2012 或以上版本。3. 实现技术:ASP.NET MVC+EF(100 分)或 ASP.NET+三层+EF(90 分)。两个字段都不能为空。数据库设计1. 创建订单项目数据库(OrdersDB)。2. 创建订单信息表(OrderInfo),信息表结构见表 1。编码完整示例:手动添加dataEF引入数据库这里的名称写【Order】就行。

红目香薰 3332

全面学习ASP.NET MVC5+EF6+EasyUI项目实战源码

ASP.NET是一个用于开发动态网页的服务器端技术,由微软公司开发。它是.NET框架的一部分,提供了编写Web应用程序和Web服务的编程模型。ASP.NET拥有多种版本,其中ASP.NET Core是一个跨平台的、开源的版本,可用于构建高性能的Web应用和API。EasyUI允许开发者通过自定义CSS来创建属于自己的主题和皮肤,以满足企业级应用对于界面外观的个性化需求。主题是包含了一套颜色和样式规则的CSS文件,可以全局改变应用的外观。

weixin_42576804的博客 923

ASP.NET MVC源码

ASP.NET Web API 是一种框架,用于轻松构建可以由多种客户端(包括浏览器和移动设备)访问的 HTTP 服务。ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台。 可以把WebApi看成Asp.Net项目类型中的一种,其他项目类型诸如我们熟知的WebForm项目,Windows窗体项目,控制台应用程序等。 WebApi类型项目的最大优势就是,开发者再也不用担心客户端和服务器之间传输的数据的序列化和反序列化问题,因为WebApi是强类型的,可以自动进行序列化和反序列化,一会儿项目中会见到。 下面我们建立了一个WebApi类型的项目,项目中对产品Product进行增删改查,Product的数据存放在List列表(即内存)中。

[ASP.NET]分析MVC5源码,并实现一个ASP.MVC

本节内容不是MVC入门教程,主要讲MVC原理,实现一个和ASP.NET MVC类似基本原理的项目. MVC原理是依赖于ASP.NET管道事件基础之上的.对于这块,可阅读上节内容 [ASP.NET]谈谈IIS与ASP.NET管道 本节目录: MVC简介 MVC5源码 实现一个MVC MVC简介 随着技术的发展,现在已经将MVC模式等同于...

denaoderenhuan8776的博客 373

Asp.net Mvc开源论坛mvcforum中版源码

Asp.net Mvc开源论坛mvcforum中版源码

ASP.NET MVC源码分析

MVC4 源码分析(Visual studio 2012/2013) HttpModule中重要的UrlRoutingModule 9:this.OnApplicationPostResolveRequestCache); 10:this.PostResolveRequestCache(context); IRouteHandler routeHandler =...

angnienong7638的博客 349

asp.net mvc5 源代码

微软的asp.net mvc5的源码

asp.net mvc网站源代码

使用asp.net mvc开发的网站源代码,包含了数据和网站的所有代码,使用了asp.net下面的mvc,dbms等几种主要技术,框架结构清晰,改一下就可以做为中小型网站的模版用了

【转】ASP.NET MVC学习笔记-MVC运行机制之源码剖析

学习ASP.NET MVC已经有段时间了,以前都是断断续续的了解了下, 对于ASP.NET MVC路由及运行机制一直不是很了解, 在网络上找了好多资料无非都是讲解了下如何添加ASP.NET MVC路由及创建自定义视图引挚等. 因此最近这几天, 下载了ASP.NET MVC源码好好研究了一翻, 将其运行机制记录下来, 一来整理下自己的理解思路, 加强自己的理解, 二来也希望对学习ASP.NET的后来...

weixin_30886233的博客 113

asp.net mvc项目源码

很庞大的源代码资料,结合MVC和三层架构的技术在内

Asp.Net Mvc 运行机制原理分析

最近一段时间接手过的项目都是基于Asp.Net的,以前对aspnet运行机制有一个大概的了解,总觉得不够透彻,按自己的理解来分析一下。 Asp.Net 运行机制 理解mvc运行原理的前提是要了解aspnet运行原理,这方面网上资料多如牛毛,我这里就大致说一下aspnet生命周期 Http请求到IIS后,如果是静态资源则IIS读取后返回客户端,动态请求被isap.dll 转发自net托管平...

vs2008ASPNET的专栏 5195

VSAN数据救援实战:当26个虚拟机突然不可访问时我们做了什么?

本文深度复盘了一次由运维操作失误引发的VMware vSAN存储危机,导致26个虚拟机数据不可访问的实战救援过程。文章详细剖析了vSAN脑裂状态的诊断方法,分享了在官方支持受限时,如何结合社区智慧与自主分析,通过精准的底层命令干预和状态推理,最终成功恢复全部数据的破局思路与操作细节,为vSAN数据救援提供了宝贵经验。

weixin_35749786的博客 236

java写一个多人线上聊天室

课程作业谔谔

weixin_51614848的博客 1136

ASP.NET MVC 入门

入门基础 ASP.NET MVC 是微软系列基于 C# 语言的 Web 开发框架,并不适合 0 基础入门,在学习之前你必须要了解 4 个知识点: 1、HTML 基础。网页的基本标签,结合 ASP.NET MVC 自带的 HTML 辅助方法来开发网页。 2、CSS 基础。修改页面样式,使得页面看起来更美观。 3、JavaScript 基础。和用户进行交互,表单验证是最基本的。 4、C# 基础语法。...

码农在途的博客 1125

SAP 关于WPS上传文件提示“文档中不包含数据“ 和“程序正在运行中“处理办法

最近这一周经常有用户反馈,使用WPS上传文件系统报错,一直提示“程序正在运行中”,另外在导入数据的时候提示"文档中不包含数据",跟进运维过程中遇到的这两种情况,分享一下处理的办法,如果各位更好的办法也可以给我留言分享。

我小时候很黑的博客 2844

【图书介绍】《ASP.NET MVC高效构建Web应用》

ASP.NET MVC高效构建Web应用》以目前流行的ASP.NET MVC 5、HTML和Razor为主线,全面系统地介绍ASP.NET MVC Web应用开发的方法,配套提供实例源码、PPT课件与作者一对一QQ答疑服务。

夏天又到了的专栏 1445

UFS Link Startup全流程解析:从硬件初始化到链路稳定的5个关键阶段

本文详细解析了UFS Link Startup的全流程,从硬件初始化到链路稳定的5个关键阶段,包括初始化阶段、数据通道发现、数据通道重新对齐、链路启动收尾和能力交换阶段。通过时序分析、代码实现和实际案例,帮助开发者掌握UFS协议链路启动的技术细节,确保设备与主机之间的可靠通信。

weixin_30687051的博客 429

残差检验_第三十讲 R语言-Cox比例风险模型的假设检验条件

在介绍完 Cox比例风险模型的详细理论和R实现以后(插入链接!!!),我们已经知道Cox比例风险模型可以较好的同时矫正多个混杂因素对结果的影响,同时我们遗留下来了一个问题:Cox比例风险模型的假设检验条件是什么?这一讲,我们将对此进行解答。请注意,如果使用不当,统计模型可能会产生误导性的结论。因此,检查给定的模型是否适合数据类型是非常重要的!1. Cox比例风险模型的假设条件Cox比例风险模型的成...

weixin_35476698的博客 8047

ASP.NET MVC源代码下载。

http://aspnet.codeplex.com/ 现在最高版本ASP.NET MVC 3.0   http://aspnet.codeplex.com/wikipage?title=MVC&referringTitle=Home ASP.NET MVC ASP.NET MVC is a free, fully supported Microsoft framework fo

蓝叶菱的专栏 3878

VLA算法总结对比——RT1 / RT2 / Pi0 / Octo/ RDT / OpenVLA

本文主要针最近比较经典的VLA算法进行对比总结,暂不涉及到代码细节和实验细节上的展开,仅仅是从大面上掌握下目前VLA的一些思路和方法。

weixin_44580210的博客 9492
上一篇: Asp.Net Mvc: Implement your custom ModelBinder
下一篇: VC++内存泄露定位
study_live
博客等级 码龄19年 20粉丝 27原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值