当IIS收到一个http请求,把请求信息发给对应的HttpModel(实际是实现类UrlRoutingModule),在HttpModel中会注册HttpApplication 类中的PostResolveRequestCache事件,通过此事件来动态选择映射HttpHandler处理程序。通过匹配到的RouteData类的RouteHandler属性得到IRouteHandler对象(MVC4是MvcRouteHandler、asp.net原生的是PageRouteHandler),通过这个对象的GetHttpHandler方法就可以得到HttpHandler处理程序。具体代码如下:

public virtual void PostResolveRequestCache(object sender, EventArgs e) {

   HttpApplication app = (HttpApplication)sender;

       HttpContextBase context = new HttpContextWrapper(app.Context);
//详细见附1
RouteData routeData = RouteCollection.GetRouteData(context);
if (routeData == null) {
return;
}
//详细见附1
IRouteHandler routeHandler = routeData.RouteHandler;
if (routeHandler is StopRoutingHandler) {
return;
}
RequestContext requestContext = new RequestContext(context, routeData);
context.Request.RequestContext = requestContext;
IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
if (httpHandler is UrlAuthFailureHandler) {
if (FormsAuthenticationModule.FormsAuthRequired) {
UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
return;
}
else {
throw new HttpException(401, SR.GetString(SR.Assess_Denied_Description3));
}
}
context.RemapHandler(httpHandler);//动态指定HttpHandler
}

附1:

RouteCollection.GetHttpHandler方法获取匹配当前路由信息的RouteData,此方法是循环遍历RouteCollection集合并调用集合中RouteBase(实现类为Route)的GetRouteData方法,并返回第一个不为Null的Roudata。Roudata实在RoudataBase的GetRouteData方法中被创建的,详见如下代码:

 public override RouteData GetRouteData(HttpContextBase httpContext) {
string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
RouteValueDictionary values = _parsedRoute.Match(requestPath, Defaults);
if (values == null) {
return null;
}
//为Roudata指定IRouteHandler对象
RouteData routeData = new RouteData(this, RouteHandler);
if (!ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest)) {
return null;
}
foreach (var value in values) {
routeData.Values.Add(value.Key, value.Value);
}
if (DataTokens != null) {
foreach (var prop in DataTokens) {
routeData.DataTokens[prop.Key] = prop.Value;
}
}
return routeData;
} public class RouteData {
private IRouteHandler _routeHandler;
public RouteData() {
}
public RouteData(RouteBase route, IRouteHandler routeHandler) {
Route = route;
RouteHandler = routeHandler;
}
//更多代码
}

MVC4:动态指定到HttpHandler后,就是处理Controller的创建和Action的执行了

HttpHandler根据Routedata获取到Controller的名称,然后通过ControllerBuilder的静态方法GetControllerFactory获取IControllerFactory的实现类(默认是DefaultControllerFactory )来创建请求的IController的实现类的实例。最后执行IController的Execute方法并传入请求上下文,方法Execute实现在System.Web.Mvc.ControllerBase这个抽象类中,Execute最终调用的是System.Web.Mvc.Controller中的ExecuteCore方法,ExecuteCore方法主要是保存TempData然后根据路由数据调用执行Action。代码如下:

protected override void ExecuteCore()
{
PossiblyLoadTempData();
try
{
string actionName = GetActionName(RouteData);
//ActionInvoker是System.Web.Mvc.Controller的属性,该属性是一个返回类型为IActionInvoker的action执行器
if (!ActionInvoker.InvokeAction(ControllerContext, actionName))
{
HandleUnknownAction(actionName);
}
}
finally
{
PossiblySaveTempData();
}
}

asp.net与MVC4的路由原理和过程【学习笔记】的更多相关文章

  1. Asp.net core 2.0.1 Razor 的使用学习笔记(五)

    按说这里应该写关于Role角色类的笔记,但是我还没时间实验这块,所以等以后我搞定了再来分享.现在先写其他部分. Asp.net core 2.0.1 Razor 的使用学习笔记——建立模型 按照微软官 ...

  2. Asp.net core 2.0.1 Razor 的使用学习笔记(六)

    Asp.net core 2.0.1 Razor 的使用学习笔记——基本页面的建立 VS这版(vs版本:15.5.6  .net版本:4.7.02558)的Razor页面自动生成就是坑爹货,它自动生成 ...

  3. Asp.net core 2.0.1 Razor 的使用学习笔记(一)

    环境:vs2017 版本:15.5.6 一.新建项目 1.文件>新建>项目>Visual c#>.NET Core>ASP.NET Core Web应用程序(“.NET ...

  4. Asp.net core 2.0.1 Razor 的使用学习笔记(三)

    ASP.net core 2.0.0 中 asp.net identity 2.0.0 的基本使用(二)—用户账户及cookie配置 修改用户账户及cookie配置 一.修改密码强度和用户邮箱验证规则 ...

  5. Asp.net core 2.0.1 Razor 的使用学习笔记(四)

    ASP.net core 2.0.1 中 asp.net identity 2.0.1 的基本使用(三)—用户注册 一.修改用户注册 1.打开Pages文件夹>Account>Regist ...

  6. Asp.net core 2.0.1 Razor 的使用学习笔记(二)

    ASP.net core 2.0.1 中 asp.net identity 2.0.1 的基本使用(一)—启用用户管理 一.修改和启用默认的用户账户管理和角色管理 在Data目录中添加Applicat ...

  7. Web常见安全漏洞原理及防范-学习笔记

    公司在i春秋上面报的一个课程.http://www.ichunqiu.com/course/55885,视频学习. OWASP (Open Web Application Secutiry Proje ...

  8. java NIO 原理解析之学习笔记

    关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...

  9. 在 ASP.NET Core 中发送邮件遇到的坑_学习笔记

    功能需求 因为项目需要有个忘记密码验证邮箱再重新修改密码的功能,然后我选用了很简单的一个方案,通过验证登录用户的邮箱然后发送邮件,通过这个邮件发送的链接地址来最后实现密码修改的小功能. 项目环境及实现 ...

随机推荐

  1. java07 map

    map底层,数组加链表 集合: 是一个对象,只不过这个对象可以容纳别的对象.存放对象就是操作地址. List:是有序可重复的. Set:无顺序,不可重复,有重复则后面把前面的覆盖. Map:键值对. ...

  2. systemtap 技巧系列 +GDB

    http://blog.csdn.net/wangzuxi/article/category/2647871

  3. linux-memory-buffer-vs-cache

    http://stackoverflow.com/questions/6345020/linux-memory-buffer-vs-cache

  4. [置顶] gridview中嵌套gridview(并实现子gridview的数据绑定),页面传值,加密,数据绑定

    先来张效果图 gridview 中嵌套gridview的原理是这样的,在父gridview中建一个摸板列,然后再模版列当中在放入子gridview,然后再父gridview的OnRowDataBoun ...

  5. .net System.TypeInitializationException 类型初始值设定项引发异常

    错误原因:静态字段连接数据库内容错误(应为Integrated Security=True) 果然解决! 来自:http://blog.csdn.net/zhang1597116/article/de ...

  6. java基础加强

    一.泛型 Generic 1.集合泛型: 在没有泛型之前,集合中存入的数据,类型就会丢失掉,在取出数据时,需要做强制类型转换,就有转换失败的风险,而这种风险,在编译阶段是没有办法检查出来的 引入泛型后 ...

  7. 20160420javaweb之文件上传和下载

    一.文件上传 1.提供表单允许用户通过表单选择文件进行上传 表单必须是POST提交 文件输入框必须有name属性,只有有name属性的输入项浏览器才会进行提交 需要设置enctype属性值为multi ...

  8. 如何在windows server 2008的桌面上显示 我的电脑

    装完windows server2008 r2 x64后发现桌面只有一个回收站图标,这一点和xp 20003都差不多,但是xp 2003很容易就把桌面上的 我的电脑 我的文档 网上邻居找到,但是win ...

  9. mysql:1153 Got a packet bigger than ‘max_allowed_packet’ bytes的解决方法

    备份还原或数据导入报错1153:Got a packet bigger than'max_allowed_packet'bytes的问题 这个问题可以有2个解决方法: 1.临时修改: mysql> ...

  10. 如何在Angular2中使用Forms

    在Angular2中形成两个基本对象是Control和ControlGroup. 控制用户输入 Control 一个控制表示一个输入字段(ngFormControl) 一个控制可以绑定到一个input ...