First look at the lifecycle of the classic ASP. NET processing pipeline.
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/443568/201706/443568-20170628175935711-291920395. PNG "style=" margin:0px auto;padding:0px;border:0px; "/>
We know that an ASP. NET application can have multiple HttpModule, but only one httphandler, and through this HttpHandler beginprocessrequest (or ProcessRequest) to process and return the request, view the claims processing The pipeline cycle shows that in Maphttphandler this cycle will be based on the requested URL to query the corresponding HttpHandler, then it is how to find it.
Find the HttpModules configuration section in System Web. config, and find a IHttpModule configuration named UrlRoutingModule-4.0 in the penultimate line, which is the key to finding HttpHandler. The following is an analysis of the UrlRoutingModule code:
650) this.width= 650, "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
protected virtual void init (httpapplication application) { if (Application. Context.items[_contextkey] != null) { return; } application. Context.items[_contextkey] = _contextkey; application . postresolverequestcache += onapplicationpostresolverequestcache; } private void onapplicationpostresolverequestcache (object sender, Eventargs e) { HttpApplication app = ( HttpApplication) sender; httpcontextbase context = new httpcontextwrapper (app. Context); &nBsp; postresolverequestcache (context); } public virtual void postresolverequestcache (HttpContextBase context) { RouteData routeData = Routecollection.getroutedata (context);...... iroutehandler routehandler = routedata.routehandler; ...... requestcontext requestcontext = new requestcontext ( Context, routedata); context. Request.requestcontext = requestcontext; ihttphandler httphandler = routehandler.gethttphandler (RequestContext); ...... conteXt. Remaphandler (HttpHandler);}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
You can see that UrlRoutingModule set up a Postresolverequestcache event handling method, This method finds the corresponding route data Routedata (including controller name, action name, etc.) from routecollection by matching the request. Then get an instance of Iroutehandler from the property Routehandler of Routedata and get the corresponding IHttpHandler instance from the Iroutehandler instance. Finally, call HttpContext's Remaphandler method to set remaphandlerinstance again for HttpContext.
Based on the preceding ASP. NET initialization Process Analysis 2 We know that the Classic mode and integrated mode use different iexecutionstep when acquiring HttpHandler, and the Classic mode uses the Maphandlerexecutionstep Integrated mode Materializehandl Erexecutionstep, see Execute method for both.
Look at Materializehandlerexecutionstep first.
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
void iexecutionstep.execute () { httpcontext context = _application. Context; httprequest request = context. request; ihttphandler handler = null; string configType = null; ...... if (context. Remaphandlerinstance != null) { wr. Setscriptmapforremaphandler (); context. Handler = context. remaphandlerinstance; }
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
You can see the materializehandlerexecutionstep in the UrlRoutingModule module if the remaphandlerinstance is set in HttpContext, The HttpContext handler is set directly with Remaphandlerinstance.
Look at Maphandlerexecutionstep again.
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
void Iexecutionstep.execute () {HttpContext context = _application. Context; HttpRequest request = context. Request; ... context. Handler = _application. Maphttphandler (context, request. RequestType, request. Filepathobject, request. Physicalpathinternal, false/*useappconfig*/); ......}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
The Maphttphandler method of HttpApplication is called in Maphandlerexecutionstep to set the handler of the HttpContext. See the Maphttphandler code below:
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
internal ihttphandler maphttphandler (httpcontext context, string Requesttype, virtualpath path, string pathtranslated, bool useappconfig) { IHttpHandler handler = (context. serverexecutedepth == 0) ? context. remaphandlerinstance : null; using (new Applicationimpersonationcontext ()) { if (handler != null) { return handler; } ...... }
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
From the first line of code you can see that if HttpContext's remaphandlerinstance is not empty, it will return directly to HttpContext Remaphandlerinstance (Context.serverexecutedepth refers to whether the page uses the Httpserverutility.execute to jump within the page). This also uses the Remaphandlerinstance set in HttpContext in the UrlRoutingModule module, As for the case where HttpContext does not have a remaphandlerinstance set, how to find HttpHandler based on the default extension is not discussed here.
Through the above analysis, we can imagine that by registering routedata in the static RouteCollection property in UrlRoutingModule and setting the Iroutehandler of the Routedata (an interface, There is only one method Gethttphandler used to get HttpHandler) to implement the correspondence between the route and HttpHandler. The following is an analysis of how Mvchandler is registered through the route, first of all to see the implementation of RouteCollection
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
public RouteCollection RouteCollection { get { if (_ Routecollection == null) { _routeCollection = RouteTable.Routes; } return _routeCollection; } set { routecollection = value; }}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
Can see RouteCollection is actually packaged routetable in the static routes, if there is MVC project experience should be familiar with, General MVC program in Global.asax generally have such a section to register the route:
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
protected void application_start () { ...... Routeconfig.registerroutes (routetable.routes); ...... } public class RouteConfig { public static void registerroutes (RouteCollection Routes) { routes. Ignoreroute ("{resource}.axd/{*pathinfo}"); routes. MapRoute ( name: "Default", url: " {Controller}/{action}/{id} ", defaults: new { controller = "Home", action = "Index" ", id = urlparameter.optional } ); } }
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
And the mvchandler of our defined routing settings is in the Maproute method, which is an extension method, defined in System.Web.Mvc.RouteCollectionExtensions:
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
Public static route maproute (This routecollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { ...... route route = new route (Url, new mvcroutehandler ()) { Defaults = createroutevaluedictionaryuncached (defaults), constraints = createroutevaluedictionaryuncached (Constraints), datatokens = new routevaluedictionary () }; ...... routes. ADD (Name, route); return route;}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
You can see that the Maproute registered route is bound to a mvcroutehandler as a iroutehandler, see below How Mvcroutehandler is implemented:
Protected virtual IHttpHandler Gethttphandler (RequestContext requestcontext) {requestContext.HttpContext.SetSes Sionstatebehavior (Getsessionstatebehavior (RequestContext)); return new Mvchandler (RequestContext); }
Here you see the code to create the Mvchandler at last.
At this point, we should have a clear understanding of the We use a global set of static properties (Routetable.routes) to add a variety of route (but should be preceded by the HttpModule initialization cycle, typically using httpapplication created cycles in Application_ The Start method adds the route rules we need, and of course adds the Mvchandler to this important httphandler when adding routes. It then obtains the requested Routedata and its properties Iroutehandler instances by looking up the registered route through UrlRoutingModule in the Postresolverequestcache cycle (as to how the route matches, and so on). , and then through the Iroutehandler instance can get IHttpHandler and set it to the Remaphandlerinstance property of HttpContext through Gethttphandler. Finally, a different HttpHandler is implemented in the Maphttphandler cycle by acquiring the remaphandlerinstance of the HttpContext to take over the URLs that match the different routes.
Enter MVC processing Channel