I've been on this almost 2 days and I'm really feeling stuck. I've been running a site for a few years using MapPageRoute to create urls for several hundred "pages" that are all handled by "~/default.aspx" via database lookups for page data. The entire site is not like this (i.e. it's not a single page site), but a good portion is.
It has been working fine except I am unable to use querystrings on the mapped routes. The RegisterRoutes method in the global.asax is:
public static void RegisterRoutes(RouteCollection routes)
{
routes.Clear();
routes.Ignore("{resource}.ashx/{*pathInfo}"); //ignore ashx files
routes.Ignore("{resource}.axd/{*pathInfo}"); //ignore axd files, prevents javascript/routing collisions
routes.MapPageRoute("SitePage", "{*page_url}", "~/default.aspx", false);
}
I use a wildcard on the path segment. Unfortunately only one wildcard is allowed. {*page_url} typically represents 1 to 4 segments. I've tried various forms of IRouteHandler and IHttpHandler code, but I don't see how to change the url that appears in the client browser. I can use the wildcard this way because none of the routes interfere with a physical files.
The only reason I want to preserve the querystring is because Google Adwords adds on a ?gclid=xxxxxxxxx string to an ad link, and Google Analytics .js uses that querystring to report back.
A sample URL depiction of the issue is:
/about-us/community/philanthropy (resolves fine)
/about-us/community/philanthropy?gclid=xxxxxxx (redirects back to:)
/about-us/community/philanthropy
My web.config is free of url-rewriting settings that might affect this.
A fair amount of my research on SO and elsewhere is for MVC sites. This is a WebForms site.
Example, similar question, but for MVC: How do I route a URL with a querystring in ASP.NET MVC?
I abandoned the routing engine for this altogether and went to path rewriting. My pattern didn't neatly fit routing.
I got some help from Chris Zhao Is it possible to have Routing maintain a querystring in the browser address bar?
And this link was really helpful for some more in depth context: URL rewriting in an ASP.NET application
In global.asax at Application_BeginRequest:
if (Request.CurrentExecutionFilePathExtension == "" && Request.CurrentExecutionFilePath != "/"
&& g.Global.SITEPAGEROOTS.ContainsKey(Request.Url.Segments[1].Replace("/", "")))
{
Context.RewritePath("/default.aspx", false);
}
The g.Global.SITEPAGEROOTS is a Dictionary singleton with < 30 entries and it just hangs out in memory until garbage collection. It contains the base path, primary url segment for my sitepages that need to be url-rewritten. Also, the "false" turns off rebaseClientPath which helped with images and other items that weren't showing on the pages due to using application root directory references (~/).
In the /default.aspx page:
var rawUri = new Uri(Request.Url, Request.RawUrl);
//using RawUrl because the url is usually rewritten before hitting this page
//and RawUrl preserves the original url.
if (rawUri.LocalPath != "/" && rawUri.LocalPath != "/default.aspx")
{
//lookup the rawUri.LocalPath in the db and pull out all the site page
//data needed to render the page (html, metas, etc.)
//querystring found at rawUri.Query if needed.
}