当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. VOA学习-South Sudan Must Allow Aid

    South Sudan Must Allow Aid The United States is gravelyconcerned by the serious escalation of the hu ...

  2. Poco库网络模块例子解析1-------字典查询

    Poco的网络模块在Poco::Net名字空间下定义   下面是字典例子解析 #include "Poco/Net/StreamSocket.h" //流式套接字 #include ...

  3. Android 自定义View修炼-仿QQ5.0 的侧滑菜单效果的实现

    有一段时间没有写博客了,最近比较忙,没什么时间写,刚好今天有点时间, 我就分享下,侧滑菜单的实现原理,一般android侧滑的实现原理和步骤如下:(源码下载在下面最后给出哈) 1.使用ViewGrou ...

  4. 转:oracle ebs po模块一揽子采购协议小结

    转自:http://yedward.net/?id=193 oracle ebs po模块一揽子采购协议小结 本文总结oracle ebs采购订单(po)模块一揽子采购协议的相关知识,总结如下: 1. ...

  5. [置顶] linux第二天,g++,gcc,ps,cat,sort,grep,kill,less,ls -l ,

    33.less sample.txt 分页输出文件内容到屏幕 34./search content (搜索内容) 可以将文档中有searchcontent 的行输出到屏幕 35.grep scienc ...

  6. 7.Composer的安装和使用

    1.安装Composer: 局部安装 要真正获取 Composer,我们需要做两件事.首先安装 Composer (同样的,这意味着它将下载到你的项目中): curl -sS https://getc ...

  7. uboot源码解析

    实例:1.3.4版本at91sam系列 GPIO部分: 一.初始化: include\asm-arm\arch-at91sam9\gpio.h 1.同一引脚的复用设置 2.输入输出初始化寄存器 3.得 ...

  8. iOS toolbar

    初学ios,对toolbar初步了解: self.navigationItem.title=@"显示工具栏"; // 显示工具栏 //self.navigationControll ...

  9. WildFly 9.0.2 启用 SSL

    一.最近做个项目是需要在WildFly中启用https,但是由于WildFly的中文文档比较少所以google了一下,先是通过JBOSS的官方文档了解了一下,但是官方文档这块的配置介绍有些不全面.所以 ...

  10. MVC小系列(二十一)【带扩展名的路由可能失效】

    mvc3之后:如果路由带上扩展名,比如这样: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRout ...