Tuesday 3 March 2009

ASP.net MVC Framwork Part 3

In my previous post, I wrote about the Microsoft ASP.Net MVC Framework and demonstrated with the help of a simple application, how it simplifies the use Model-View-Controller design pattern in web applications. The ultimate motive for using the patter is of course to achieve seperation of business and presentation logic.

In this post, I will write about what actually happens under the hood in the MVC framework and how does it enables us to create more simpler applications. The underlying technology used in the MVC framework is not new. If you are familiar with the Micorosoft Internet Information server (IIS), you would have surely heard about ISAPI Extensions and ISAPI Filters.

ISAPI Extensions are program that run on the IIS web server and have access to the functionality provided by IIS. They are the ultimate target of all web requests and are responsible for processing them. ISAP Filters are programs through which all client requests are filtered through before they are finally processed by ISAPI extensions.

To harness the functionality of ISAPI Exentions and ISAPI filter, ASP.Net provides Http Handlers and Http Modules respectively. A following pictures gives a graphical representation of a web request through HTTP Modules and HTTP Handlers.


The HTTP Handler class must implement the IHTTPHandler interface in the System.Web namespace. For every type of web request, an HTTP handler must exist to preocess it. In a web application, the Http Handlers to process different kinds of files are listed in the web.config file. The following code snippet shows an example of all HTTP

<system.webServer>

<modules runAllManagedModulesForAllRequests="true">

<remove name="ScriptModule"/>

<remove name="UrlRoutingModule"/>

<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

</modules>


<handlers>

<remove name="ScriptHandlerFactory"/>
<remove name="ScriptHandlerFactoryAppServices"/>
<remove name="ScriptResource"/>
<remove name="MvcHttpHandler"/>
<remove name="UrlRoutingHandler"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</handlers>

</system.webServer>


As you might have guessed so far, the functionality of MVC framework is provided through HTTP Module and HTTP Handlers, which provides all the functionailty of routing and passing data between controller and view.

To process the custom URL, the framework make use of UrlRoutingModule. In the above extract from web.config, you will find the the entry

<add name="urlRouting" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing"/>

A RouteTable needs to be defined to handle the URL pattern. This is done in the Application_OnStart event in the global.asax file. This is shown below:

public static void RegisterRoutes(RouteCollection routes)

{

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

}



protected void Application_Start()

{

RegisterRoutes(RouteTable.Routes);

}


Inside the method RegisterRoute, there is a call routes.MapRoute, which takes three parameter. The first parameter is the name of the route, the second parameter contains the pattern of URL and the three parameter contains default values for URL.

As you can see, the pattern used in URL is "{Controller}/{Action}/{Id}". When the URL is called, the class in the controller section is called as controller, the action value is set through the action part of URL and if there is a record selected then the Id is passed through the Id section.
The HTTP module System.Web.Routing.UrlRoutingModule makes sure that requests are passed to controller and that all data submitted from the view is passed to it.

No comments: