Alexander Beletsky's development blog

My profession is engineering

Inside ASP.NET MVC: Route to MvcHandler

In my previous post I promised to start with exploration of MvcHanlder as entry point of ASP.NET MVC application. MvcHandler plays the major role in MVC infrastructure, but as I fugured out - the whole story does not begin there. The story is actually begins inside ASP.NET framework.

ASP.NET framework

ASP.NET framework is heart of ASP.NET MVC application. Basically, ASP.NET is a request processing engine. It takes incoming request as input and sends it through internal pipeline till the end point. The architecture allows extensibility, you could plug either into pipeline (modules) or end points (handlers). Interesting fact that ASP.NET designed to be decoupled from actual request source. So, the source of request could be any application - IIS, Cassini or any custom one.

We could imagine that each request pass through the set of filters (internal pipeline) lands up on request handler (end point), request handler creates a response object and sent it back. There are a lot of hidden details of dealing with managed/unmanaged code that you could find in this brilliant article by Rick Strahl.

For us it is important to understand two basic abstractions, HttpModules and HttpHandlers.

HttpModules and HttpHandlers

From the developers point of view the difference between those are: one implements IHttpModule interface another implements IHttpHandler interface.

Module participates in the request processing of every request in order to change or add to it in some way.

Handler is responsible for handling the request and producing the response for specific content types.

ASP.NET MVC is HttpHandler.

MVC handler

There a bunch of default HttpModules and HttpHandlers in your IIS configuration. Just take a look here - %WINDOWS%\Microsoft.NET\Framework\v4.0.30319\Config\web.config.

But if you look closer you won’t notice any mention of System.Web.Mvc.MvcHanlder. Hey. what’s wrong? How the runtime actually knows that MvcHanler have to be called to handle our request? That was absolutely unclear to me at very beginning.

From request to handler

I opened WebRuntime.sln and found all references to MvcHandler. It is only one place there, in the MvcRouteHandler (MvcRouteHandler.cs) class. MvcRouteHandler implements IRouteHandler interface, with one single method GetHttpHandler. I put the breakpoint there and started application for debug.

MVC route handler

As application got started I halted on breakpoint with such call stack:

MVC debug

Let’s try to read and decrypt it.

It begins with WebDev.WebHost40.dll (Cassini Web Server) that receives request and System.Web.HttpRuntime.ProcessRequest. Here is ASP.NET framework start to work:

  1. ProcessRequestInternal method called. This is the primary method of whole pipeline. First, it initialize the HttpContext object.
  2. System.Web.Dll ProcessRequestInternal
  3. Next it get HttpApplication instance, initialize it and calls either BeginProcessRequest for IHttpAsyncHandler or ProcessReques for IHttpHandler.
  4. System.Web.dll GetApplicationInstance
  5. If I go to global.asax.cs of our application it is clear that System.Web.HttpApplication implementation is inherited and System.Web.HttpApplication is a usual IHttpAsyncHandler. So, async BeginProcessRequest starts.
  6. HttpApplication
  7. In BeginProcessRequest there is a cycle that iterates all modules and execute each of it. Reflector code looks messy, but the point is clear
  8. System.Web.dll ExecuteSteps
  9. And finally, the control goes to UrlRoutingModule that calls our factory method for MvcHandler. Aha!

UrlRouting module

UrlRouting is an HttpModule, registered in global web.config:

UrlRouting register

The goal of this module is basically matching incoming request by URL with pre-defined Route configuration and return corresponding handler for this request. In PostResolveRequestCache method it gets the RouteHandler and asks for corresponding HttpHanlder.

Wow, I didn’t know that!.. UrlRouting plays a major role inside the MVC infrastructure. But there the Routes are initialized and how MvcRouteHandler is associated with request?

Back to roots - Application_Start() method

I should actually start from here, Application_Start() is entry point of application. By my journey turn to be just other way around.

Application_Init()

Inside the RegisterRoutes we register route by giving: route name and constraints.

MVC map route

The MapRoute is actually extension method in RouteCollectionExtensions.cs.

MVC register route

Now, you can see how the route with particular URL is being register and associated with MvcRouteHandler.

Putting it all together

Now it is time to get deep breath and finally understand the route of HTTP request to MvcHttpHandler. Here we go:

  • ASP.NET framework starting to process incoming request in ProcessRequest method, but interesting stuff going in ProcessRequestInternal
  • ProcessRequestInternal calls GetApplicationInstance method that get application instance and calls it Application_Init()
  • Application_Init() registers routes that map URL (like “home/index”) with MvcRouteHandler instance
  • ASP.NET framework starts to iterate modules for incoming request and found UrlRouting module
  • UrlRouting module matches incoming request URL with registered collections of Routes
  • For found matched Route it gets corresponding route handler (MvcRouteHandler)
  • MvcHandler is being returned by GetHttpHandler of MvcRouteHandler

That’s the routing that is being executed each time you put URL and hit your browser button.

What’s next?

I hope next time we indeed look closer to MvcHandler :).

Previous: Inside ASP.NET MVC: Part 2: Setting up project for hacking Next: Inside ASP.NET MVC: All begins here - MvcHanlder