在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
我们在上一篇文章中介绍Controller激活系统中所涉及到的一些类型,比如有关Controller类型的相关定义类型就包括了IController类型,IAsyncController类型,ControllerBase抽象类型和我们最终要使用的抽象类型Controller,这是ASP.NET MVC 框架中和Controller本身定义相关的类型。其他辅助类型,包括管理Controller的类型ControllerFactory,这个工厂负责Controller的生产和销毁。我们还涉及到另一个辅助类型,用于把系统默认定义的或者自定义的ControllerFactory注册到ASP.NET MVC框架中的类型ControllerBuilder。 1 [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")] 2 public class UrlRoutingModule : IHttpModule 3 { 4 private static readonly object _contextKey = new object(); 5 6 private static readonly object _requestDataKey = new object(); 7 8 private RouteCollection _routeCollection; 9 10 public RouteCollection RouteCollection 11 { 12 get 13 { 14 if (this._routeCollection == null) 15 { 16 this._routeCollection = RouteTable.Routes; 17 } 18 return this._routeCollection; 19 } 20 set 21 { 22 this._routeCollection = value; 23 } 24 } 25 26 protected virtual void Dispose() 27 { 28 } 29 30 protected virtual void Init(HttpApplication application) 31 { 32 if (application.Context.Items[UrlRoutingModule._contextKey] != null) 33 { 34 return; 35 } 36 application.Context.Items[UrlRoutingModule._contextKey] = UrlRoutingModule._contextKey; 37 application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache); 38 } 39 40 private void OnApplicationPostResolveRequestCache(object sender, EventArgs e) 41 { 42 HttpContextBase context = new HttpContextWrapper(((HttpApplication)sender).Context); 43 this.PostResolveRequestCache(context); 44 } 45 46 [Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")] 47 public virtual void PostMapRequestHandler(HttpContextBase context) 48 { 49 } 50 51 public virtual void PostResolveRequestCache(HttpContextBase context) 52 { 53 RouteData routeData = this.RouteCollection.GetRouteData(context); 54 if (routeData == null) 55 { 56 return; 57 } 58 IRouteHandler routeHandler = routeData.RouteHandler; 59 if (routeHandler == null) 60 { 61 throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0])); 62 } 63 if (routeHandler is StopRoutingHandler) 64 { 65 return; 66 } 67 RequestContext requestContext = new RequestContext(context, routeData); 68 context.Request.RequestContext = requestContext; 69 IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); 70 if (httpHandler == null) 71 { 72 throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[] 73 { 74 routeHandler.GetType() 75 })); 76 } 77 if (!(httpHandler is UrlAuthFailureHandler)) 78 { 79 context.RemapHandler(httpHandler); 80 return; 81 } 82 if (FormsAuthenticationModule.FormsAuthRequired) 83 { 84 UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this); 85 return; 86 } 87 throw new HttpException(401, SR.GetString("Assess_Denied_Description3")); 88 } 89 90 void IHttpModule.Dispose() 91 { 92 this.Dispose(); 93 } 94 95 void IHttpModule.Init(HttpApplication application) 96 { 97 this.Init(application); 98 } 99 } 具体来说,该组件通过以RouteTable的静态属性Routes表示的路由表针对当前请求实施路由解析,如果有匹配,就会根据路由对象Route来生成RouteData路由数据对象,然后我们借助RouteData对象的RouteHandler属性获取想要的HttpHandler对象。在默认情况下这个RouteHandler属性所代表的对象是MvcRouteHandler。翠花,上代码: 1 /// <summary>Creates an object that implements the IHttpHandler interface and passes the request context to it.</summary> 2 public class MvcRouteHandler : IRouteHandler 3 { 4 private IControllerFactory _controllerFactory; 5 6 /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcRouteHandler" /> class.</summary> 7 public MvcRouteHandler() 8 { 9 } 10 11 /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcRouteHandler" /> class using the specified factory controller object.</summary> 12 /// <param name="controllerFactory">The controller factory.</param> 13 public MvcRouteHandler(IControllerFactory controllerFactory) 14 { 15 this._controllerFactory = controllerFactory; 16 } 17 18 /// <summary>Returns the HTTP handler by using the specified HTTP context.</summary> 19 /// <returns>The HTTP handler.</returns> 20 /// <param name="requestContext">The request context.</param> 21 protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) 22 { 23 requestContext.HttpContext.SetSessionStateBehavior(this.GetSessionStateBehavior(requestContext)); 24 return new MvcHandler(requestContext); 25 } 26 27 /// <summary>Returns the session behavior.</summary> 28 /// <returns>The session behavior.</returns> 29 /// <param name="requestContext">The request context.</param> 30 protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext) 31 { 32 string text = (string)requestContext.RouteData.Values["controller"]; 33 if (string.IsNullOrWhiteSpace(text)) 34 { 35 throw new InvalidOperationException(MvcResources.MvcRouteHandler_RouteValuesHasNoController); 36 } 37 IControllerFactory controllerFactory = this._controllerFactory ?? ControllerBuilder.Current.GetControllerFactory(); 38 return controllerFactory.GetControllerSessionBehavior(requestContext, text); 39 } 40 41 /// <summary>Returns the HTTP handler by using the specified request context.</summary> 42 /// <returns>The HTTP handler.</returns> 43 /// <param name="requestContext">The request context.</param> 44 IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) 45 { 46 return this.GetHttpHandler(requestContext); 47 } 48 } 在该类型里面包含了一个IControllerFactory类型成员字段,这个接口类型是所有ControllerFactory都要必须实现的接口,否则就不叫Controller的工厂了。MvcRouteHandler类型有两个构造函数,无参的没的说,另一个需要传递一个IControllerFactory类型的参数,这个参数用于初始化MvcRouteHandler类型内部包含的类型为IControllerFactory的_controllerFactory字段。当我们构造MvcRouteHandler实例的时候,如果我们调用了无参的构造函数,它会在内部使用ControllerBuilder.Current.GetControllerFactory()方法来获取我们通过ControllerBuilder类型注册的IControllerFactory类型的实例,代码很明显: IControllerFactory controllerFactory = this._controllerFactory ?? ControllerBuilder.Current.GetControllerFactory();
MvcRouteHandler实现了IRouteHandler接口,目的只有一个,提供后续的HttpHandler,IRouteHandler接口定义如下: public interface IRouteHandler { IHttpHandler GetHttpHandler(RequestContext requestContext); } MvcRouteHandler会给我们直接返回MvcHandler对象,这个对象用于处理请求,包括激活Controler对象,代码最有说服力,这份代码,上篇文章也贴过,现在也贴一下把,上代码: 1 public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState 2 { 3 private struct ProcessRequestState 4 { 5 internal IAsyncController AsyncController; 6 7 internal IControllerFactory Factory; 8 9 internal RequestContext RequestContext; 10 11 internal void ReleaseController() 12 { 13 this.Factory.ReleaseController(this.AsyncController); 14 } 15 } 16 17 private static readonly object _processRequestTag = new object(); 18 19 internal static readonly string MvcVersion = MvcHandler.GetMvcVersionString(); 20 21 /// <summary>Contains the header name of the ASP.NET MVC version.</summary> 22 public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version"; 23 24 private ControllerBuilder _controllerBuilder; 25 26 internal ControllerBuilder ControllerBuilder 27 { 28 get 29 { 30 if (this._controllerBuilder == null) 31 { 32 this._controllerBuilder = ControllerBuilder.Current; 33 } 34 return this._controllerBuilder; 35 } 36 set 37 { 38 this._controllerBuilder = value; 39 } 40 } 41 42 /// <summary>Gets or sets a value that indicates whether the MVC response header is disabled.</summary> 43 /// <returns>true if the MVC response header is disabled; otherwise, false.</returns> 44 public static bool DisableMvcResponseHeader 45 { 46 get; 47 set; 48 } 49 50 /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary> 51 /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns> 52 protected virtual bool IsReusable 53 { 54 get 55 { 56 return false; 57 } 58 } 59 60 /// <summary>Gets the request context.</summary> 61 /// <returns>The request context.</returns> 62 public RequestContext RequestContext 63 { 64 get; 65 private set; 66 } 67 68 /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary> 69 /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns> 70 bool IHttpHandler.IsReusable 71 { 72 get 73 { 74 return this.IsReusable; 75 } 76 } 77 78 /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcHandler" /> class.</summary> 79 /// <param name="requestContext">The request context.</param> 80 /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext" /> parameter is null.</exception> 81 public MvcHandler(RequestContext requestContext) 82 { 83 if (requestContext == null) 84 { 85 throw new ArgumentNullException("requestContext"); 86 } 87 this.RequestContext = requestContext; 88 } 89 90 /// <summary>Adds the version header by using the specified HTTP context.</summary> 91 /// <param name="httpContext">The HTTP context.</param> 92 protected internal virtual void AddVersionHeader(HttpContextBase httpContext) 93 { 94 if (!MvcHandler.DisableMvcResponseHeader) 95 { 96 httpContext.Response.AppendHeader(MvcHandler.MvcVersionHeaderName, MvcHandler.MvcVersion); 97 } 98 } 99 100 /// <summary>Called by ASP.NET to begin asynchronous request processing.</summary> 101 /// <returns>The status of the asynchronous call.</returns> 102 /// <param name="httpContext">The HTTP context.</param> 103 /// <param name="callback">The asynchronous callback method.</param> 104 /// <param name="state">The state of the asynchronous object.</param> 105 protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) 106 { 107 HttpContextBase httpContext2 = new HttpContextWrapper(httpContext); 108 return this.BeginProcessRequest(httpContext2, callback, state); 109 } 110 111 /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary> 112 /// <returns>The status of the asynchronous call.</returns> 113 /// <param name="httpContext">The HTTP context.</param> 114 /// <param name="callback">The asynchronous callback method.</param> 115 /// <param name="state">The state of the asynchronous object.</param> 116 protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) 117 { 118 IController controller; 119 IControllerFactory factory; 120 this.ProcessRequestInit(httpContext, out controller, out factory); 121 IAsyncController asyncController = controller as IAsyncController; 122 if (asyncController != null) 123 { 124 BeginInvokeDelegate<MvcHandler.ProcessRequestState> beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState) 125 { 126 IAsyncResult result; 127 try 128 { 129 result = innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState); 130 } 131 catch 132 { 133 innerState.ReleaseController(); 134 throw; 135 } 136 return result; 137 }; 138 EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> endDelegate = delegate(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState) 139 { 140 try 141 { 142 innerState.AsyncController.EndExecute(asyncResult); 143 } 144 finally 145 { 146 innerState.ReleaseController(); 147 } 148 }; 149 MvcHandler.ProcessRequestState invokeState = new MvcHandler.ProcessRequestState 150 { 151 AsyncController = asyncController, 152 Factory = factory, 153 RequestContext = this.RequestContext 154 }; 155 SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext(); 156 return AsyncResultWrapper.Begin<MvcHandler.ProcessRequestState>(callback, state, beginDelegate, endDelegate, invokeState, MvcHandler._processRequestTag, -1, synchronizationContext); 157 } 158 Action action = delegate 159 { 160 try 161 { 162 controller.Execute(this.RequestContext); 163 } 164 finally 165 { 166 factory.ReleaseController(controller); 167 } 168 }; 169 return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag); 170 } 171 172 /// <summary>Called by ASP.NET when asynchronous request processing has ended.</summary> 173 /// <param name="asyncResult">The asynchronous result.</param> 174 protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) 175 { 176 AsyncResultWrapper.End(asyncResult, MvcHandler._processRequestTag); 177 } 178 179 private |
请发表评论