当前位置:编程学习 > asp >>

ASP.NET MVC 3—一切的开始MvcHandler、MvcHttpHandler

在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文件中添加如下代码:

        protec

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,