Getting QueryString Values From A Rewritten URL / ASP.NET Routing URL

During today’s similcast of the ASP.NET Firestarter in Atlanta, G. Andrew Duthie discussed .NET 4’s new support for routing — or, what everyone in Web development calls “URL rewriting.” *

Someone online asked, “If I use routing, can I access query string variables using JavaScript?”

The question isn’t as confused as it sounds on the surface. Of course, if one uses routing / URL rewriting, it’s to remove query string variable and make them part of what appears to be a permanent file structure.

In other words, this:

http://www.server.com/path/to/file.aspx?v1=foo&v2=bar

Becomes this:

http://www.server.com/path/to/file/v1/foo/v2/bar/

The questioner really means, is there a way, after rewriting a URL, to extract key->value pairs from it via JavaScript? The answer is yes; rather than using the location.search property, which allows JavaScript to get the querystring parameters of a URL, we use location.pathname to get the part of the URL that follows the domain, and use that to create our key->value pairs.

In the case of query strings, one can, in JavaScript, use location.search to get query string pairs from the current URL.

alert(location.search);

If we invoke this JavaScript on the first URL, we get the entire query string, including the question mark.

Then, to get the key-value pairs, we’d simply strip off the leading question mark, then split the remaining string into an associative array, like so:

//get key->value pairs
var qs = location.search;
qs = qs.substring(1);
var a = qs.split('&');

var b;
var i;
var output = new Array();

for(i = 0; i < a.length; i++) {
	//split each key->value pair
	b = a[i].split('=');
	//add each pair to output array
	output[b[0]] = b[1];
}

Of course, we can’t use location.search to get query string variables if we’ve made those variables part of the file path, as in a URL rewrite / Routing. We get a null string if we try.

But we can use location.pathname to get the URL to our file, and modify our JavaScript to create key->value pairs from that URL:

//get key->value pairs from URL
var qs = location.pathname;
//strip leading path slash
qs = qs.substring(1);

var a = qs.split('/');
var i;
var output = new Array();

for(i = 0; i < a.length; i += 2) {
	//append key->value pairs to output array
	output[a[i]] = a[i + 1];
}

Alternative: A URL That Does Not Begin With Key->Value Pairs

The example above assumes that we have a URL patterned specifically after key-value pairs, and that those pairs begin at the start of the URL. In other words, the above rewritten / routed URL and JavaScript would create an array like:

output['v1'] == 'foo';
output['v2'] == 'bar';

So we’d need to modify this JavaScript if the rewritten / routed URL does not begin immediately with key->value pairs. For example, suppose this is our rewritten URL:

http://www.server.com/store/category/toys/type/dolls/maker/mattel/

In this case, let’s suppose that “store” isn’t part of the key->value chain we want. Or, to make it plainer, if we were using a query string, this is how the URL would look:

http://www.server.com/store.php?category=toys&type=dolls&maker=mattel/

In that case, we’d need to adjust our for loop to skip over “store,” since it isn’t relevant to the key->value pair extraction. We can do that quite easily by simply starting the for loop at 1, rather than zero:

//get key->value pairs from URL
var qs = location.pathname;
//strip leading path slash
qs = qs.substring(1);

var a = qs.split('/');
var i;
var output = new Array();

for(i = 1; i < a.length; i += 2) {
	//append key->value pairs to output array
	output[a[i]] = a[i + 1];
}

If the URL looked like this:

http://www.server.com/site/store/category/toys/type/dolls/maker/mattel/

And “site” and “store” aren’t part of the key->value array we want to build, then we would start the for loop at 2, rather than 0.

Note that we can also end the for loop early, if the URL has trailing path information that shouldn’t be considered part of the key->values array.

Keyless Array

Another option here is to rewrite / route our URLs without keys.

Let’s look at the store URL sample, above. We know that we want to get values for category, type and maker. But probably every URL our JavaScript will process is always going to have those elements in the same order.

In other words, every URL that comes to our page is going to have category first, then type, then maker. So do we even need keys? Our URL could be much shorter and simpler if we eliminated them:

http://www.server.com/toys/dolls/mattel/

Our JavaScript is also much simpler: We can now use the initial split of the filepath variable.

//get key->value pairs from URL
var qs = location.pathname;
//strip leading path slash
qs = qs.substring(1);

var output = qs.split('/');
//output[0] == 'toys'
//output[1] == 'dolls'
//output[2] == 'mattel'

The Right Rewriting / Routing Rules Make A Big Difference

If you’ve chosen the proper URL rewrite / routing rules, you shouldn’t have to even work this hard to extract your former query string key->value pairs. The right pattern is key.

All links in this post on delicious: http://www.delicious.com/dougvdotcom/getting-querystring-values-from-a-rewritten-url-asp-net-routing-url

* Why Microsoft feels the need to re-brand common technologies is beyond me. It took them forever to adopt URL rewriting officially; and while “routing” is technically a correct description of what a rewrite engine does, it only makes it harder for developers to discuss patterns and practices with others when Microsoft insists on calling roses by other names.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • Check out the Commenting Guidelines before commenting, please!
  • Want to share code? Please put it into a GitHub Gist, CodePen or pastebin and link to that in your comment.
  • Just have a line or two of markup? Wrap them in an appropriate SyntaxHighlighter Evolved shortcode for your programming language, please!