在ASP.NET MVC3里面,一次用户请求是如何开始的呢?

如果下载了MVC的源代码进行调试,一般来说会发现开始于MvcHandler,简单看下MvcHandler的代码,主要就是通过控制器的工厂接受控制器的实例,并使用控制器进行进一步处理,那么MvcHandler是如果被创建,如何被调用执行的?

首先看看MvcHandler的构造函数,是没有无参的构造函数,显然看来MvcHandler单干是有点难度了。直接查找MvcHandler的所有引用,很容易在MvcRouteHandler中可以找到:

        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) {
            requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
            return new MvcHandler(requestContext);
        }

而且使用MvcHandler构造函数的地方有且仅有这么一个,明显我们找到我们想要的东西了。

接下来就需要弄清楚MvcRouteHandler的GetHttpHandler什么时候执行的,看源代码的时候,“查找所有引用”是很好用的功能,在RouteCollectionExtensions里面可以看到:

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults,
      object constraints, string[] namespaces) {
            if (routes == null) {
                throw new ArgumentNullException("routes");
            }
            if (url == null) {
                throw new ArgumentNullException("url");
            }
 
            Route route = new Route(url, new MvcRouteHandler()) {
                Defaults = new RouteValueDictionary(defaults),
                Constraints = new RouteValueDictionary(constraints),
                DataTokens = new RouteValueDictionary()
            };
 
            if ((namespaces != null) && (namespaces.Length > 0)) {
                route.DataTokens["Namespaces"] = namespaces;
            }
 
            routes.Add(name, route);
 
            return route;
        }

这个就比较好理解了,MvcRouteHandler实现了 IRouteHandler接口,因此可以与路由模块进行集成,当我们在Global.asax文件中使用MapRoute方法时,会向路由模块注册MvcRouteHandler实例,当MvcRouteHandler被调用的时候,会创建RequestContext实例产生MvcHandler的实例,并使用MvcHandler实例进一步进行处理。查看在UrlRoutingModule的代码可以看到:

 public virtual void PostResolveRequestCache(HttpContextBase context)
    {
        RouteData routeData = this.RouteCollection.GetRouteData(context);
        if (routeData != null)
        {
            IRouteHandler routeHandler = routeData.RouteHandler;
            if (routeHandler == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, 
         SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
            }
            if (!(routeHandler is StopRoutingHandler))
            {
                RequestContext requestContext = new RequestContext(context, routeData);
                context.Request.RequestContext = requestContext;
                IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
                if (httpHandler == null)
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, 
          SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[] { routeHandler.GetType() }));
                }
                if (httpHandler is UrlAuthFailureHandler)
                {
                    if (!FormsAuthenticationModule.FormsAuthRequired)
                    {
                        throw new HttpException(0x191, SR.GetString("Assess_Denied_Description3"));
                    }
                    UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
                }
                else
                {
                    context.RemapHandler(httpHandler);
                }
            }
        }

到此为止MvcHandler的整个创建过程就差不都已经弄清楚,那么接下来继续介绍MvcHttpHandler,也许有人会问既然已经有MvcHandler了为什么还需要MvcHttpHandler呢?

其实前面也提到过了,MvcHandler没有无参的构造函数,因此即使MvcHandler实现了 IHttpHandler接口,在IIS中也不能将其映射为某类文件扩展名的处理程序,需要结合路由模块使用。那么MvcHttpHandler就提供了不通过路由模块的情况下直接处理映射的处理程序。

至于如何将某类文件扩展名映射到一个MVC处理程序,在此就不多做介绍,但MvcHttpHandler带无参的构造函数,而且继承UrlRoutingHandler类实现了IHttpHandler接口,因此可以在ASP.NET程序中灵活的使用用来解决一些问题。

例如创建一个普通的MVC3项目,但在项目中添加一个WebForm页面TestPage.aspx,在页面的后台文件TestPage.aspx.cs文件中添加如下代码:

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpContext.Current.RewritePath("/Home/About");
            IHttpHandler httpHandler = new MvcHttpHandler();
            httpHandler.ProcessRequest(HttpContext.Current);
        }

然后直接访问/TestPage.aspx页面,会发现实际访问返回了/Home/About页面。

调试查看访问/TestPage.aspx执行的过程,还会发现最终还是使用到MvcHandler,至于为什么会这样子?有兴趣的话可以看下UrlRoutingHandler的ProcessRequest的逻辑就能够理解了。

转载于:https://www.cnblogs.com/sugarcane/archive/2011/05/25/2057475.html

ASP.NET MVC 3—一切的开始MvcHandler、MvcHttpHandler相关推荐

  1. [ASP.NET MVC 小牛之路]10 - Controller 和 Action (2)

    继上一篇文章之后,本文将介绍 Controller 和 Action 的一些较高级特性,包括 Controller Factory.Action Invoker 和异步 Controller 等内容. ...

  2. ASP.NET MVC 控制器激活(一)

    ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...

  3. Asp.net MVC生命周期

     Asp.net应用程序管道处理用户请求时特别强调"时机",对Asp.net生命周期的了解多少直接影响我们写页面和控件的效率.因此在2007年和2008年我在这个话题上各写了一篇文 ...

  4. 【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链 (转)

    你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...

  5. 从零开始学习 ASP.NET MVC 1.0 (三) Controller/Action 深入解析与应用实例 【转】

    一.摘要 一个Url请求经过了Routing处理后会调用Controller的Action方法. 中间的过程是怎样的? Action方法中返回ActionResult对象后,如何到达View的? 本文 ...

  6. asp.net MVC 的处理流程

    之前把笔记都放在空间日志中隐藏起来,今天看到这句话:作为经常从网上索取免费资料的一员,要有回报的思想,也为了让更多的人少走些弯路,想想自己不能这么自私,所以把空间日志搬到博客园来.闲话不说,直接开始. ...

  7. asp.net MVC 路由机制 Route

    1:ASP.NET的路由机制主要有两种用途: -->1:匹配请求的Url,将这些请求映射到控制器 -->2:选择一个匹配的路由,构造出一个Url 2:ASP.NET路由机制与URL重写的区 ...

  8. ASP.NET MVC笔记

    ASP.NET MVC的应用程序生命周期还是跟原来ASP.NET WebForm一样没有区别,只是引入MVC后,加了一个UrlRoutingModule模块,该模块用来捕获应用程序生命周期中的Post ...

  9. Asp.net MVC防止图片盗链的实现方法,通过自定义RouteHandler来操作

    本文告诉你如何在ASP.NET MVC中实现一个自定义RouteHandler来防止其他人盗链你的图片. 首先,我们来回顾一下当一个请求发往ASP.net MVC站点时的情景,IIS收到请求并将请求转 ...

最新文章

  1. 在octopress中增加“返回顶部”按钮
  2. c++ 纯虚函数和抽象类那些事(一)
  3. Cisco QOS之CBWFQ
  4. 事业单位考试计算机科学与技术试题的答案,事业单位考试计算机基础知识试题答案...
  5. 160826、浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘
  6. 模型算法_详解SVM模型之SMO算法
  7. C# yield简单迭代
  8. WPS简历模板的图标怎么修改_最新8000套设计师面试作品集:模板+插画+海报+图标+简历...
  9. C语言中有关字符串的库函数(3)
  10. 初探linux子系统集之led子系统(三)【转】
  11. Android判断当前使用数据流量的是哪张卡
  12. PHP 7革新与性能优化
  13. RDS电台 TA 与 AF解释
  14. 超稳定的接口——淘宝/天猫获得淘宝商品详情
  15. 难以置信,网易首席架构师竟用了 500 页笔记,把网络协议给趣谈了
  16. win10如何显示我的电脑在桌面
  17. Delphi变成小技巧——直接将excel当做表来显示
  18. MyISAM 和 InnoDB 的区别
  19. HTTP Keep-Alive 学习
  20. 一套简单实用的SQL脚本,总有你需要的

热门文章

  1. Chrome 73 稳定版正式发布,macOS 支持暗色主题
  2. SNMP学习(2)——SNMP实战
  3. Android XML文件读写
  4. win7 ie9总是跳转到官方主页的解决方法
  5. 语法错误: leftparen 应在 colon 之前
  6. Heaps 高性能游戏引擎
  7. 用Redis实现Session功能
  8. (bower、grunt、gulp、jspm、karmam、webpack) 前端工程自动化开发工具
  9. 麦克风阵列能干这么多事你知道吗?
  10. Tensorflow学习笔记-第二节程序结构