I'm a huge fan of ASP.NET Routing. It gained popularity as the part of ASP.NET MVC
which channels requests for a given URL to the right controller action. In a
wise move, Microsoft moved the routing infrastructure out of ASP.NET MVC
and
into its own assembly with the release of .NET 3.5 SP1.
With ASP.NET Routing you can construct search engine optimized and human friendly URLs such as
these:
Here part of the URL (
tag or
user) selects the page and part of the URL
(
everything or
codinghorror) are effectively query parameters to the page.
This is well documented in the ASP.NET MVC
world running on your server - you can't get anything done without it in
MVC. But what about Windows Azure? What if you don't want
ASP.NET MVC? What if you're a traditional type of person and want all the goodness that comes with what is now
called ASP.NET WebForms (aka "normal ASP.NET")?
In this brief post, I'll cover how to use ASP.NET routing and ASP.NET WebForms in Azure.
The sample project can be downloaded if you want to follow along.
Phil Haack has
written a good post on using routing alongside ASP.NET WebForms so I won't cover too much background information.
How does this change for Azure?
The short answer is that it doesn't. If you get routing working for IIS 7 in your web app, you can effectively deploy it to Azure.
But the steps always felt convoluted to me when reading others' write-ups on this. So let's run through converting a Windows Azure Web Role (essentially a "stock" ASP.NET WebForms
app) to use routing in Azure.
First you'll need the Azure SDK and Visual Studio tools:
- Next, create a new solution in Visual Studio by choosing Cloud Service->Web and Worker Cloud Service.
- Add a new Global.asax file to your web role project.
- Add a reference to System.Web.Routing and System.Web.Abstractions in your web role project.
- Define a custom class that derives from IRouteHandler which will map
URL parameters into the HttpContext for use in your pages:
internal class CustomRoute : IRouteHandler
{
public CustomRoute(string virtualPath)
{
VirtualPath = virtualPath;
}
public string VirtualPath { get; private set; }
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
foreach ( var aux in requestContext.RouteData.Values )
{
HttpContext.Current.Items[aux.Key] = aux.Value;
}
return BuildManager.CreateInstanceFromVirtualPath(
VirtualPath, typeof( Page ) ) as IHttpHandler;
}
}
- Register these routes in the Application_Start method of your Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add( "ShowName",
new Route(
"naming/show/{name}",
new CustomRoute( "~/ShowName.aspx" )
) );
RouteTable.Routes.Add( "CreateAccount",
new Route(
"account/begin",
new CustomRoute( "~/Account.aspx" )
) );
RouteTable.Routes.Add( "Home",
new Route(
"home",
new CustomRoute( "~/Default.aspx" )
) );
}
Now if you run your app, you might expect the routing infrastructure to work. Inside
the ASP.NET Dev Server (aka cassini) this will likely work. But in the Azure Development Fabric you'll
see this:

The problem is you need to tell IIS 7.5 to get out of the way and let the request get to ASP.NET.
-
We'll define a class to short-circuit the IIS validation
class Iis7RoutingHandler : UrlRoutingHandler
{
protected override void VerifyAndProcessRequest(
IHttpHandler httpHandler, HttpContextBase httpContext)
{
}
}
- Modify the web.config by adding a handler and module to the system.webServer section:
...
-
Finally, we need to recover the data passed to the page. For example, in the sample project we have:
route: /naming/show/{name}
example: /naming/show/michael-kennedy
How will our page access the value of name? Recall that our custom route stashes the values in
HttpContext.Current.Items. We'll just pull them back out as follows in our Page_Load method of our ASPX class:
LabelName.Text = (string)HttpContext.Current.Items["name"];
That's it! You can see our routes working in our WebForms app running in Azure (well, technically the screenshot
is the dev fabric - but it works in the cloud as well):
Download the source and try it for yourself: AzureRoutingSample.zip (136 KB)