About Links Archives Search Feed Albums of Note


ASP.NET 4.0 Part 11, Configuring Routing Is Easier

Welcome to part 11 of my tour through ASP.NET 4.0 [http://blog.hmobius.com/post/2010/02/09/ASPNET-40-Cometh.aspx]. In this episode, we’re going to take a look at how routing for webforms has been made easier to set up in ASP.NET 4.0. This will be followed up in Part 12 with a look at the new route-aware classes, methods and properties in more detail.

Routing was originally introduced in ASP.NET 3.5 SP1 as part of the foundations to enable the ASP.NET MVC template engine to work. It could also be used against the webforms engine but a certain amount of rolling-your-own-foundation coding was required to enable it properly.

In ASP.NET 4.0, that initial legwork is no longer necessary as routing for webforms is now supported as standard in System.Web, the majority of the configuration for routing is pre-set in system-wide config files, and some extra goodness has been added into various classes for ease of use as well. All in all, if you haven’t had occasion to try routing with webforms before, try it with ASP.NET 4.0. It’s really simple.

Why? There are a metric [http://www.4guysfromrolla.com/articles/012710-1.aspx] / boatload [http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx] / of articles [http://mostlylucid.net/archive/2009/01/25/asp.net-4.0-webform-routing-quick-rsquon-dirty-version.aspx] introducing routing and how it works. In a nutshell, routing, like URL rewriting, is a response to two general criticisms of websites.

  1. We humans prefer it if a page’s URL is readable. For example, http://myforums.info/forum-Music is easier to read than http://myforums.info/forum.aspx?id=2. It’s easier to remember too 2. Search engines prefer human-readable URLs as well. In particular, they like URLs with no querystring parameters at the end. And, the more search engine friendly a site’s URLs are, the better indexed they may be by a search engine and the higher they may appear in search rankings. (Obviously, URLs aren’t the only thing indexing robots look at when they come to your site - Descriptions and Keywords [http://blog.hmobius.com/post/2010/02/22/ASPNET-40-Part-6-New-Page-Directive-Attributes.aspx] are up there with a host of other things [http://www.amazon.co.uk/exec/obidos/ASIN/0470131470/hmobiuscom-21] too - but they certainly help.)

So then, the major consequence of routing as far as webforms is concerned are URLs which are more readable for humans and search robots alike with no reduction of information to the page itself.

How? Routes are initialized as named, regular expressions (using a subset of the standard .NET RegEx syntax) and given an order in which they will be matched against the currently requested URL. For example,

  1. user-{username} 2. forum-{forumname} 3. forum-{forumname}/thread-{threadid}

Let’s say a request comes to the server for http://myforums.info/forum-Music.

Routing Is Neither URL Rewriting nor Redirection Hopefully, the above description should differentiate routing from URL rewriting and page redirection. However, just in case it didn’t…

Setting Up Webforms Routing In ASP.NET 3.5 Briefly, here are the steps needed to enable routing for webforms in ASP.NET 3.5.

  1. All routing classes and namespaces are found in a new DLL, System.Web.Routing.dll to be included as a reference in your website. 2. The UrlRoutingModule needs to be added to the list of modules enabled for the site in web.config (as described here in MSDN [http://msdn.microsoft.com/en-us/library/cc668202.aspx]) 3. A handler class inheriting IRouteHandler needs to be created that understands how to resolve the route into the page or handler that will actually process the request and generate the RouteData collection. Both Phil Haack [http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx] and Chris Cavanagh [http://chriscavanagh.wordpress.com/2008/03/11/aspnet-routing-goodbye-url-rewriting/] put forward basic implementations of this handler, discussing potential security issues. 4. Register the routes for the site in the Application_Start handler of global.asax using your new route handler class. For example,

protected void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes)

{

// Route existing files (default will shortcut routing if physical file exists)

RouteTable.Routes.RouteExistingFiles = true;

// Add StopRoutingHandler for .axd and .asmx requests

routes.Add(new Route("{resource}.axd/{*pathInfo}",

new StopRoutingHandler()));

routes.Add(new Route("{service}.asmx/{*pathInfo}",

new StopRoutingHandler()));

// Add existing routes

routes.Add(“Users”, new Route(“user-{username}”,

new WebFormRouteHandler(“~/users.aspx”, true)));

routes.Add(“Forums”, new Route(“forum-{forumname}”,

new WebFormRouteHandler(“~/forum.aspx”, true)));

routes.Add(“Threads”, new Route(“forum-{forumname}/thread-{threadid}”,

new WebFormRouteHandler(“~/thread.aspx”, true)));

// Add an unnamed handler for all unknown requests (now created in the PageRoute table)

//routes.Add(new Route(“{value}”,

new WebFormRouteHandler(“~/pages/default.aspx”)));

}

  1. Write your pages as you would normally using the RouteData collection in place of the Querystring class. You’ll need to make RouteData available by passing a RequestContext object to the object that needs access to the RouteData. Again, Phil Haack suggests one way of doing this (via an IRoutableObject interface) here [http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx]. 6. Finally, you have to configure IIS to have ASP.NET deal with requests to your routes, thus passing them on to your RouteHandler classes. If you’re using IIS6 and your routes are extension-less (i.e. missing .aspx, .asmx , .ashx etc file extensions in their composition), you’ll need to configure wildcard maps on a per-directory level according to where your routes point else you’ll end up serving all your static files with ASP.NET as well. Full instructions for this come courtesy of Steve Sanderson (Part 1 [http://blog.stevensanderson.com/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/] , Part 2 [http://blog.stevensanderson.com/2008/07/07/overriding-iis6-wildcard-maps-on-individual-directories/] ).

Setting Up Webforms Routing In ASP.NET 4.0 By comparison, the procedure is far more straightforward in ASP.NET 4.0, thanks in large part to Microsoft being able to open up and edit System.Web and the classes inside it. Let’s compare

  1. System.Web.Routing has been folded into System.Web.dll in .NET 4.0 so there is no need for an additional reference to it in your solution. 2. The UrlRoutingModule is also already set up in the machine-wide web.config file which means that it works straight off the bat in IIS 6. For IIS 7 users, however, you’ll need to enable it with the following addition to web.config.

… <system.webServer> </system.webServer>

  1. ASP.NET 4.0 includes an implementation of IRouteHandler for you to use - it’s called PageRouteHandler. There’s no reason why you can’t build your own as before, but it’s no longer necessary. 4. You still need to register routes for your application but if you’re using the built-in PageRouteHandler class, you can use the MapPageRoute helper method to make route registration clearer.

protected void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes)

{

// Route existing files (default will shortcut routing if physical file exists)

RouteTable.Routes.RouteExistingFiles = true;

// Add StopRoutingHandler for .axd and .asmx requests

routes.Add(new Route("{resource}.axd/{*pathInfo}",

new StopRoutingHandler()));

routes.Add(new Route("{service}.asmx/{*pathInfo}",

new StopRoutingHandler()));

// Add existing routes with MapPageRoute helper method

routes.MapPageRoute(“Users”, “user-{username}”, “~/users.aspx”);

routes.MapPageRoute(“Forums”, “forum-{forumname}”, “~/forum.aspx”, true);

// MapPageRoute is equivalent to adding a Route with the PageRouteHandler like so

routes.Add(“Threads”, new Route(“forum-{forumname}/thread-{threadid}”,

new PageRouteHandler(“~/thread.aspx”, true)));

}

  1. Any pages you write now automatically have access to the RouteData collection as a property of the Page class itself, as well as several other route-aware additions we’ll review in the next section.

protected void Page_Load(object sender, EventArgs e) { lblHello.Text = RouteData.Values[“username”] == null ? “Hello Mr A. Nonymous” : String.Format(“Hello {0}”, RouteData.Values[“username”].ToString()); }

  1. Regrettably, while integration into IIS7 Integrated Mode remains quite simple, you still need to configure IIS6  IIS7 in Classic mode to associate the routes used in your site with ASP.NET as you did in ASP.NET 3.5. That’s a failing of IIS6 rather than ASP.NET.

As you can see, setting up routing for an ASP.NET 4.0 webforms site is somewhat simpler than for the previous version as Microsoft has taken the opportunity to refactor routing into the core ASP.NET framework. In the next episode, we’ll look at several of the new route-aware features for use once in ASP.NET 4.0 sites we’ve set routing up. Until then, happy coding!

Posted on March 10, 2010   #Geek Stuff     #ASP.NET  






← Next post    ·    Previous post →