How to find IHttpHandler in asp.net mvc Routing

Source: Internet
Author: User

It has been a long time to learn how to use asp.net. Now let's analyze the whole process of mvc. I plan to write a blog post on the mvc series and analyze mvc from the source code perspective. When we are exposed to mvc, we will certainly experience routing. How did we develop routing. In our web. <add assembly = "System. web. routing, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35 "/> it seems that the Routing is responsible for it. There is a special class UrlRoutingModule in this dll.
Let's take a look at the main core code in it: Copy codeThe Code is as follows: protected virtual void Init (HttpApplication application)
{
If (application. Context. Items [_ contextKey] = null)
{
Application. Context. Items [_ contextKey] = _ contextKey;
Application. PostResolveRequestCache + = new EventHandler (this. OnApplicationPostResolveRequestCache );
}
}

Private void OnApplicationPostResolveRequestCache (object sender, EventArgs e)
{
HttpContextBase context = new HttpContextWrapper (HttpApplication) sender). Context );
This. PostResolveRequestCache (context );
}

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 );
}
}
}
}

A PostResolveRequestCache event is registered in IHttpModule. Init, which calls the PostResolveRequestCache method. In this method, there are several important codes:Copy codeThe Code is as follows: RouteData routeData = this. 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 );

Let's analyze the first RouteData routeData = this. RouteCollection. GetRouteData (context). We guess this is to get the route information. To understand this code, we have to go back to our program. In the RegisterRoutes method in the Global. asax. cs file, there is such a sentence by default.Copy codeThe Code is as follows: routes. MapRoute (
"Default", // route name
"{Controller}/{action}/{id}", // URL with Parameters
New {controller = "Home", action = "Index", id = UrlParameter. Optional} // default value of the Parameter
);

This code is mainly used to register a route. The url here should be noted that it cannot be written at will, and the controller and action are required. How is it implemented?Copy codeThe Code is as follows: 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 = 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;
}

The parameters are as follows:Copy codeThe Code is as follows: routeName = "Default", // route name
RouteUrl = "{controller}/{action}/{id}", // URL with Parameters
Defaults = new {controller = "Home", action = "Index", id = UrlParameter. Optional} // default value of the Parameter
Constraints = null
Namespaces = null

A Route instance is created and added to the RouteCollection.
Now let's go back to the RouteData routeData = this. RouteCollection. GetRouteData (context); Code. The main code for GetRouteData is as follows:Copy codeThe Code is as follows: public RouteData GetRouteData (HttpContextBase httpContext)
{
Using (this. GetReadLock ())
{
Foreach (RouteBase base2 in this)
{
RouteData routeData = base2.GetRouteData (httpContext );
If (routeData! = Null)
{
Return routeData;
}
}
}
Return null;
}

Here, base2 is the previously added Route for calling MapRoute. The GetRouteData method of Route is as follows:Copy codeThe Code is as follows: public override RouteData GetRouteData (HttpContextBase httpContext)
{
String virtualPath = httpContext. Request. AppRelativeCurrentExecutionFilePath. Substring (2) + httpContext. Request. PathInfo;
RouteValueDictionary values = this. _ parsedRoute. Match (virtualPath, this. Defaults );
If (values = null)
{
Return null;
}
RouteData data = new RouteData (this, this. RouteHandler );
If (! This. ProcessConstraints (httpContext, values, RouteDirection. IncomingRequest ))
{
Return null;
}
Foreach (KeyValuePair <string, object> pair in values)
{
Data. Values. Add (pair. Key, pair. Value );
}
If (this. DataTokens! = Null)
{
Foreach (KeyValuePair <string, object> pair2 in this. DataTokens)
{
Data. DataTokens [pair2.Key] = pair2.Value;
}
}
Return data;
}

This method is complex and involves many verification and checks. We mainly care about RouteData data = new RouteData (this, this. RouteHandler );
Of course, the remaining RequestContext requestContext = new RequestContext (context, routeData );
Context. Request. RequestContext = requestContext; the two sentences are nothing special.
Now let's take a look at IHttpHandler httpHandler = routeHandler. GetHttpHandler (requestContext); what exactly does this sentence mean to get Httphandler.
Then how does MvcRouteHandler obtain an Httphandler,Copy codeThe Code is as follows: protected virtual IHttpHandler GetHttpHandler (RequestContext requestContext ){
RequestContext. HttpContext. SetSessionStateBehavior (GetSessionStateBehavior (requestContext ));
Return new MvcHandler (requestContext );
}

An MvcHandler instance is directly returned.
The most important sentence is context. RemapHandler (httpHandler); it's easy to understand. In the RemapHandler method of HttpContext, there is such a sentence: this. _ remapHandler = handler;
This attribute is available in HttpContext.Copy codeThe Code is as follows: internal IHttpHandler RemapHandlerInstance
{
Get
{
Return this. _ remapHandler;
}
}

So when will this item be called? The void HttpApplication. IExecutionStep. Execute () method in the internal class MaterializeHandlerExecutionStep of HttpApplication is called.Copy codeThe Code is as follows: if (httpContext. RemapHandlerInstance! = Null)
{
HttpContext. Handler = httpContext. RemapHandlerInstance;
}

I can guess the class name MaterializeHandlerExecutionStep. The BuildSteps methods in PipelineStepManager of internal classes include:Copy codeThe Code is as follows: HttpApplication. IExecutionStep step = new HttpApplication. MaterializeHandlerExecutionStep (app );
App. AddEventMapping ("ManagedPipelineHandler", RequestNotification. MapRequestHandler, false, step );

I think you should have a general understanding of the entire mvc route here.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.