Querystring Element Insertion

One problem I frequently come across is having to redirect to a page using the current query string in the request, but also having to add new parameters. Furthermore, the parameters I want to add might already exist in the querystring, and if you’re redirecting to the same page all hell breaks loose within a few clicks of the link.

The exact problem I’m trying to solve is this: I have one page which gathers parameters from the user for an advanced product search, which then passes the parameters through the querystring to a search results page. This page contains a GridView control that has column headings which also pass some values through the querystring (information about which column to sort on and in what direction – I’ll blog about this another time). When the column is clicked, I still want to keep the information about the search and also the sort criteria. Not all of the parameters will be in the querystring at any given time.

I have to deal with this problem on a few pages, and I need a way to quickly and easily redirect to a url passing the current querystring parameters whilst at the same time injecting one or more new parameters if they don’t currently exist. If they do exist, I might want to re-assign it a new value.
The (hopefully) obvious solution is to work with the querystring while it’s still in the form of a Collection, rather than a string. Unfortunately for us, the Request.Querystring instance during a page is read-only. So how do we go about this?

What I’ve come up with is a pattern for achieving the solution, rather than a handy method or object. It’s quick, painless and flexible, and here’s the code:

Dim newQsColl As New NameValueCollection(HttpContext.Current.Request.QueryString)
newQsColl.Set(sortExpressionParam, sortExpression)
newQsColl.Set(sortDirectionParam, CType(sortDir, Integer))

Dim newQs As String = newQsColl.GlueElements("&")

The last line I’ll talke about in a second. This code snippet allows you to take the current querystring and essentially add more key/value pairs to it. Here I’ve used the ‘Set’ method to create the new key/value pairs; this method will add the new pair if the key doesn’t exist, but will change the key if it doesn’t exist. Exactly the behaviour I was after!
An extra facility I wanted to finish this off was some easy method to glue the elements together in a format I could stick straight back into a hyperlink without any fuss. You could create a special lightweight class to do this, but since I’m using Asp.Net 3.5 I used an extension method. Ideally I’d like to implement the following on any IDictionary (since that interface follows the same key/value element structure), but alas NameValueCollection doesn’t inherit from such an interface.
Nevertheless here’s my extension method, named ‘GlueElements’:

<Extension()> _
Public Function GlueElements(ByVal collection As NameValueCollection, _
ByVal glue As String) As String
  Dim sb As New Text.StringBuilder()
  For Each key In collection.Keys
    sb.Append(String.Format("{0}={1}{2}", key, collection(key), glue))
  Next     

  Dim result As String = sb.ToString()
  If Not String.IsNullOrEmpty(glue) Then
    result = Left(result, result.Length - glue.Length)
  End If     

  Return result
End Function

This method simply loops through the keys in the collection and joins together the keys and values using a specified ‘glue’ string. It then outputs the result, stripping off the last instance of the glue before returning it. If you set the glue string to ‘&’, you end up with a string suitable for inserting straight into a url as a querystring.

Articles ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>