In the last post I showed how to use the ASP.NET 3.5 Routing Engine for URL rewriting purposes. I want to go further in this post by adding the ability to add variables into a route path and forward and append query string variables to the destination Web Form request.

A route can contain one or more variables expressed by its {name}.

RouteTable.Routes.Add(
	new Route(
		"articles/{id}", 
		new devcoach.Web.RoutingPageHandler()));

Inside of the RoutingHandler we can iterate through the variables by accessing them by the RouteData property on the parameter passing the RequestContext:

var queryString = new StringBuilder("?"); 
foreach (var aux in requestContext.RouteData.Values) { 
  queryString.Append( 
		requestContext.HttpContext.Server.UrlEncode(aux.Key)); 
	queryString.Append("="); 
	queryString.Append(
		requestContext.HttpContext.Server.UrlEncode( aux.Value.ToString())); 
	queryString.Append("&"); 
} 
queryString.Remove(queryString.Length - 1, 1);

The problem now is that the method CreateInstanceFromVirtualPath of the BuildManager class does not allow us to pass for instance a query string as a parameter (I had this discussion recently with Holger at the speakers party of the Basta! confrence):

var handler = 
  (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(
		VirtualPath, 
		typeof(Page));

Passing URL Parameters (a query string) to the instance of the page created from its virtual path we can use the good old RewitePath method (which should be familiar for everyone who has rewritten URLs with ASP.NET 2.0):

HttpContext.Current.RewritePath(  
    string.Concat(  
        VirtualPath,  
        queryString));

var handler =  
    (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(  
        VirtualPath,  
        typeof(Page));

It feels a bit strange to use the old fashioned way of rewriting URLs just to pass a query string, but the routing handler will stay in control of the request and only the context  variables gets modified.