Transferred from: http://www.cnblogs.com/darrenji/p/3795690.html
In the previous article, "19 key links (7-12) of the ASP. NET MVC request processing pipeline life cycle ", this article continues with 7-12 key steps.
⒀ when the request arrives at UrlRoutingModule, UrlRoutingModule takes out the controller, action and other routedata information in the request, matches all the rules in the routing table, if matching, Give the request to Iroutehandler, namely Mvcroutehandler
Mvcroutehandler is used to generate mvchandler that implements the IHttpHandler interface:
namespace system.web.routing{ interface iroutehandler { IHttpHandler Gethttphandler ( RequestContext requestcontext);} }
UrlRoutingModule how to hand over the request to Mvcroutehandler?
By analyzing the source code of UrlRoutingModule, you can see:
Obtaining Routedata instances that encapsulate routing information through the static method of RouteCollection Getroutedata
Routedata Routedata = this. Routecollection.getroutedata (context);
And get Mvcroutehandler from Routedata.
Iroutehandler Routehandler = Routedata.routehandler;
Why is it possible to get Mvcroutehadnler from Routedata?
Because when we registered the route using the Maproute () method in HttpApplication's first pipeline event, the Mvcroutehandler was injected into the route through the route class's constructor.
PublicStatic Route MapRoute (This routecollection routes,String name,String URL,Object defaults,Object Constraints,String[] namespaces) {if (routes = =Null) {ThrowNew ArgumentNullException ("Routes"); }if (url = =Null) {ThrowNew ArgumentNullException ("Url"); } Route route =New Route (URL,new Mvcroutehandler ()) {Defaults = new RouteValueDictionary (defaults), Constraints = new RouteValueDictionary (constraints), Datatokens = new< Span style= "color: #000000;" > RouteValueDictionary ()}; if ((Namespaces! = 0 "namespaces namespaces;} Routes. ADD (name, route); return route;}
⒁mvcroutehandler, hand over the request to Mvchandler.
or from UrlRoutingModule source can be seen, through the HttpHandler Gethttphandler () method to achieve the IHttpHandler interface Mvchandler:
IHttpHandler HttpHandler = Routehandler.gethttphandler (requestcontext); context. Remaphandler (HttpHandler);
Mvchandler part of the source code is:
PublicClassMvchandler:ihttpasynchandler, IHttpHandler, irequiressessionstate{ProtectedInternalVirtualvoidProcessRequest (HttpContextBase HttpContext) {securityutil.processinapplicationtrust () ={IController controller; Icontrollerfactory Factory; Processrequestinit (HttpContext,Out controller,Out factory);//Initialized the ControllerfactoryTry{Controller. Execute (RequestContext); }Finally{Factory. Releasecontroller (Controller); } }); }Privatevoid Processrequestinit (HttpContextBase HttpContext,Out IController Controller,OutIcontrollerfactory Factory) {bool? isrequestvalidationenabled =Validationutility.isvalidationenabled (HttpContext.Current);if (isrequestvalidationenabled = =True) {validationutility.enabledynamicvalidation (httpcontext.current);} Addversionheader (HttpContext); Removeoptionalroutingparameters ();string controllername = RequestContext.RouteData.GetRequiredString ("controller"); Factory = controllerbuilder.getcontrollerfactory (); controller = factory. Createcontroller (RequestContext, controllername); if (Controller = = null) { throw new InvalidOperationException (String.Format ( Cultureinfo.currentculture,mvcresources.controllerbuilder_factoryreturnednull,factory. GetType (), controllername)); } }}
⒂ from the above can be seen: first through the static method of Controllerbuilder Getcontrollerfactory get to achieve Icontrollerfactory interface Controllerfactory, The controller name is then obtained from the routing data in the context, and the controller that implements the IController interface is created accordingly
Controller is derived from Controllerbase, and Controllerbase implements the IController interface. Controllerbase part of the source code is as follows:
PublicAbstractClasscontrollerbase:icontroller{ProtectedVirtualvoidExecute (RequestContext requestcontext) {if (RequestContext = =Null) {ThrowNew ArgumentNullException ("RequestContext ");} if (Requestcontext.httpcontext = = nullthrow new " requestcontext); Verifyexecutecalledonce (); Initialize (RequestContext); using (Scopestorage.createtransientscope ()) { Executecore (); }} protected abstract Void Executecore ();}
It can be viewed as:
The Execute () method of the base class Controllerbase is executed each time the controller is called
The Execute () method also calls the abstract method of Executecore ()
Executecore () The implementation of this abstract method is defined in the controller
The Executecore () method in the controller invokes the Invokeaction () method of Actioninvoker
⒃actioninvoker Firing Action Method
The Actioninvoker implements the Iactioninvoker interface:
Interface iactioninvoker{ string actionname);}
The default actioninvoker for MVC is controlleractioninvoker.
In the controller class, an attribute Actioninvoker of type iactioninvoker is provided, and when the Executecore () method is executed, the Actioninvoker call Invokeaction () method to fire the action. As follows:
PublicClasscontroller{...PrivateIactioninvoker _actioninvoker;PublicIactioninvoker Actioninvoker {Get{if (_actioninvoker = =null Createactioninvoker ();} return _actioninvoker;} set {_actioninvoker =protected virtualreturn new Controlleractioninvoker (); } public override void< Span style= "color: #000000;" > Executecore () {actioninvoker.invokeaction (...);}
Actioninvoker will need information about the Controller and action when executing the Invokeaction () method, in fact, the controller information (such as the controller's name, type, contained action, etc.) Encapsulated in the Controllerdescriptor class, action information (such as the name of the action, parameters, attributes, filters, and so on) is encapsulated in the actiondescriptor.
In addition, Actiondescriptor provides a findaction () method to find the action that needs to be executed.
⒄actioninvoker in the Execute Invokeaction () method returns ActionResult
ActionResult is an abstract class:
Class actionresult{ void Executeresult (controllercontext context);}
If the ActionResult is non-viewresult, such as Jsonresult, Contentresult, the content will be delivered directly to the response response stream and displayed to the client; Will go to the next render view link.
⒅viewengine find the view that needs to be rendered
The default is the Razor view engine and the Web Form view engine, which implements the Iviewengine interface.
Iviewengine interface Method:
Findpartialview
Findview
Releaseview
If you want to create a custom view Engine, you only need to derive from the Virtualpathproviderviewengine class.
⒆view is loaded into the webviewpage<tmodel> type and renders the generated HTML
Call Viewresult's Executeresult () method to render HTML through the iview render () method.
PublicAbstractClassviewresultbase:actionresult{PublicOverridevoidExecuteresult (ControllerContext context) {if (context = =Null) {ThrowNew ArgumentNullException ("Context"); }If(String.IsNullOrEmpty (ViewName)) {ViewName = context. Routedata.getrequiredstring ("Action"); } Viewengineresult result =nullif (View = = null// get to Viewengineresult through the view engine, and the template page "aspx" is loaded as webviewpage<tmodel> result =< Span style= "color: #000000;" > Findview (context); View = result. View; } TextWriter writer = context. HttpContext.Response.Output; ViewContext viewcontext = new ViewContext (context, View , ViewData, TempData, writer); View.render (ViewContext, writer); if (Result! = null
The 19 key segments of the ASP. NET MVC request processing pipeline life cycle include:
19 Key segments of the ASP. NET MVC Request processing Pipeline Lifecycle (1-6) ASP. 19 Key links in the lifecycle of the pipeline life cycle (7-12) ASP. 19 Key links to the lifecycle of the net MVC Request processing pipeline (13-19)