LA.NET [EN]

Mar 12

I admit it: I”m getting rusty on web development! In these last months I”ve been building Windows Forms apps with C#. So, I still didn”t had the time to look at the ASP.NET MVC platform or the new Silverlight release. Anyway, I”m hoping that this will change in a near future (which can happen even faster if I”m able to get a job that will let me write ASP.NET code full time – anyone has any offers? ๐Ÿ™‚ ,,).

When I fired .NET Reflector today and loaded the MVC dlls, I got a pleasant surprise: there”s System.Web.Mvc assembly! To me this means that the routing engine got decoupled from the MVC platform, which leads me to conclude that it should be possible to reuse the routing engine with classic ASP.NET apps (ie, Web Forms applications). When would you want to do this? Well, how about reusing it for url rewriting?

Lets try something simple built in 5 minutes by a guy (ie, me:)) which hasn”t built anything with MVC yet nor has had any time to look at its internals. First, we need to add the UrlRoutingModule (so that it is able to process the custom urls we”re adding to the routing table) by adding a new entry to the httpModule section (btw, I”m assuming that you”ve already dropped the System.Web.Routing and the System.Web.Abstractions assemblies on the bin folder of your web app):

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

After doing this, I created 2 simple pages (called Default.aspx and Default2.aspx -as you can see, I was inspired:) ). In this stupid example, I”m going to say that principal will redirect to default and other should redirect to Default2.aspx (not really what you ”d do on a real app, but my time is really limited today ๐Ÿ™ ). So, what I need to do is add these entries to the rounting table and specify the IRouteHandler that will be responsible for handling the request. The IRouteHandler”s job is returning an IHttpHandler which will handle the request and return a response to the user. In this case, we only need build a class that implements the IRouteHandler and let it instantiate the page that should handle the current request.

Lets start by specifying the entries on the routing table. You can do it on the global.asax file with this code:

static void RegisterRoutes()
{
        System.Web.Routing.RouteTable.Routes.Add(
            new System.Web.Routing.Route(“principal”, new LA.Handlers.PageHandler() ) );

        System.Web.Routing.RouteTable.Routes.Add(
            new System.Web.Routing.Route(“other”, new LA.Handlers.PageHandler()));
}
void Application_Start(object sender, EventArgs e)
{
        // Code that runs on application startup
        RegisterRoutes();
}

What we”re saying here is that all the requests to principal should be redirected to the PageHandler route handler (don”t forget to add the mvc extension if you”re trying this with IIS 6).

The PageHandler class is really simple:

namespace LA.Handlers
{
    public class PageHandler:IRouteHandler
    {

        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            IHttpHandler handler = GetHandlerFromRequestContext(requestContext);
            return handler;
        }

        private IHttpHandler GetHandlerFromRequestContext(RequestContext requestContext)
        {
            VirtualPathData pathData = requestContext.RouteData.Route.GetVirtualPath(requestContext, requestContext.RouteData.Values);
            return pathData.VirtualPath.Contains(“principal”) ?
                (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(“~/Default.aspx”, typeof(Page))
                :
                (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(“~/Default2.aspx”, typeof(Page));
        }       
    }
}

We start by getting the VirtualPathData object form the current RequestContest. This object will lets us know the current requested url and you”ll be able to create an instance of the page by using the BuildManager.CreateInstanceFromVirtualPath method. Again, do notice that the comparison I”m using is really too simple for real production code: my objective is to show how you can reuse the routing engine on a traditional ASP.NET app.

Ok, I can hear you saying: man, what about query string parameters? I”ll only use url rewriting to hide those ugly urls. Ok, no problem! here”s what you can do

  1. add an entry to the route table and specify the parameters you need
  2. pass those values to the page.

Now, the hard part is passing the values to the instantiated page. The easiest way I can think of is using the HttpContext.Items property to pass that data around. So, let”s change the principal entry so that it receives another parameter:

System.Web.Routing.RouteTable.Routes.Add(
            new System.Web.Routing.Route(“principal/{id}“, new LA.Handlers.PageHandler() ) );

The {id} will automatically collect the info you pass after principal and add it to the RouteData dictionary exposed by the RequestContext object you”ll receive on the IRouteHandler.GetHttpHandler method. The only change needed on our handler is presented on the next snippet:

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
            IHttpHandler handler = GetHandlerFromRequestContext(requestContext);
            foreach (var aux in requestContext.RouteData.Values)
            {
                HttpContext.Current.Items[aux.Key] = aux.Value;
            }
            return handler;
}

And now you”ll only have to change your page so that it checks if there”s a valid Id on the query string parameter (if you”re expecting a direct access to the page) or on the Items property of the current context. Simple, right?

3 comments so far

  1. fubeidong
    6:42 am - 6-4-2008

    Can use this MVC in ASP.NET2.0?

  2. Eraser
    9:00 am - 11-18-2008

    Great article for me. Thanks. I have only one problem. On my pc works everything ok but on the server (Win 2008, IIS7) doesnt work. When I click on the link, the page shows 404 – File or directory not found. Any idea please? Do I have to add something into the web.config?

  3. Twistitiaks
    4:23 pm - 6-18-2009

    ????? ??? ??????? ?????? ????????????? ???? ?????? ? ??????? 1000 ??????? ???.
    ? ????? ???????????? ????? ??????? ?????? ????????????? ??????????? ????????????,
    ???? ??????? ?? ??????? ??? ?????? ???????? 1000 ??????? ??? ?????? ?? ??????? ????? ?? ????? ?????????????? ?????.
    ???????????? ????? ???????? ??????????? ?????? ?? ?.2 ??.368 ?? ??????? (????????? ??????).

    ????????, ???? ???? ????? โ€” ????? ??? ????????????

    http://csfnau.kiev.ua/kipz/img/Sidorov.jpg

    …………………./??/)
    ………………..,/?../
    ………………./…./
    …………./??/”…”/???ยท?
    ………./”/…/…./……./?? ??????? ??????? ?????????????
    ……..(”(…?…?…. ?~/”…”) SIDOROV Nicolai Alexandrovich
    ……………………..”…../ ?????? ??????? ????????????
    ……….””…………. _.ยท? ??????? ?????? ??????????
    ……………………..( csfnau.kiev.ua – National aviation University – NAU Kiev
    ………………………… ??? – ???????????? ?????????? ??????????? – nau.edu.ua

    http://www.csfnau.kiev.ua/bin/news.cgi?flash=0&lang=ru&vol=last