Thursday, May 12, 2005

Update to UrlQuery Class (C#)

Update to UrlQuery Class for easier working with Url's and QueryStrings in ASP.NET. Thanks to Levi Rosol (UrlQueryString) for the code. Previous versions: Url Manipulation (C#) - Jul 22nd, 2004, Url Manipulation v2 (C#) - Sep 22nd, 2004.

You can now add a NameValueCollection to the QueryString. Replaces existing items when one with the same key exists in the collection.

For redirecting to another page, including current page QueryString, supply the page location in the constructor:

// current page is page.aspx?query=1
UrlQuery NewPage = new UrlQuery("newpage.aspx");
// redirect to newpage.aspx?query=1
Response.Redirect(NewPage.AbsoluteUri);

More examples:

UrlQuery MyPage = new UrlQuery("/path/to/file.aspx"); // parameters on the current page are added automatically
// or to get the current page: MyQuery = new UrlQuery();
// add parameter
MyPage["myparam"] = "myval1";
// add another parameter (or replace existing one)
MyPage["myparam2"] = "myval2";
Trace.Write(MyPage["myparam2"]); // returns 'myval2'
// remove parameter
MyPage["myparam2"] = null; // or string.Empty
Trace.Write(MyPage["myparam2"]); // returns ''
// create a new collection and add items
NameValueCollection nvc = new NameValueCollection();
nvc.Add("myparam","changed");
nvc.Add("myparam3","myval3");
Trace.Write(MyPage["myparam"]); // returns 'myval1'
MyQuery.Set(nvc);
Trace.Write(MyPage["myparam"]); // returns 'changed'
Trace.Write(MyPage["myparam3"]); // returns 'myval3'
Trace.Write(MyPage.Url); // returns '/path/to/file.aspx'
Trace.Write(MyPage.VirtualFolder); // returns '/path/to/'
Trace.Write(MyPage.AbsoluteUri); // returns '/path/to/file.aspx?myparam=changed&myparam3=myval3'
Trace.Write(MyPage.Get()); // returns '?myparam=changed&myparam3=myval3'
Trace.Write(MyPage.Get().Substring(1)); // returns 'myparam=changed&myparam3=myval3'

UrlQuery Class:

public class UrlQuery
{
 /// <summary>
 /// Base on current page
 /// </summary>
 public UrlQuery()
 {
  this.url = HttpContext.Current.Request.Url.AbsolutePath;
 }
 /// <summary>
 /// Base on other page
 /// </summary>
 /// <param name="value">The url of the page to reference, i.e.: '/path/to/folder/page.aspx?param1=1&amp;param2=2'</param>
 public UrlQuery(string value)
 {
  int q = value.IndexOf('?');
  if (q != -1)
  {
   this.url = value.Substring(0, q);
   this.queryString = NameValueCollection(value);
  }
  else
  {
   this.url = value;
  }
 }
 /// <summary>
 /// Get and set Url parameters
 /// </summary>
 public string this[string param]
 {
  get
  {
   return this.Get(param);
  }
  set
  {
   this.Set(param,value);
  }
 }

 private string url;
 /// <summary>
 /// The Url of the page, without QueryString
 /// </summary>
 /// <value>/path/to/folder/page.aspx</value>
 public string Url
 {
  get
  {
   return this.url;
  }
 }
 /// <summary>
 /// Returns the virtual folder the page is in
 /// </summary>
 /// <value>/path/to/folder/</value>
 public string VirtualFolder
 {
  get
  {
   return this.Url.Substring(0, Url.LastIndexOf("/") + 1);
  }
 }
 /// <summary>
 /// The AbsoluteUri
 /// </summary>
 /// <value>page.aspx?param1=1&amp;param2=2</value>
 public string AbsoluteUri
 {
  get
  {
   return this.Url + this.Get();
  }
 }
 private NameValueCollection queryString;
 /// <summary>
 /// Get the QueryString for the page
 /// </summary>
 public NameValueCollection QueryString
 {
  get
  {
   if (this.queryString != null)
   {
    return this.queryString;
   }
   else
   {
    this.queryString = new NameValueCollection(HttpContext.Current.Request.QueryString);
    return this.queryString;
   }
  }
 }
 /// <summary>
 /// Get the QueryString
 /// </summary>
 /// <returns>String in the format ?param1=1&amp;param2=2</returns>
 public string Get()
 {
  string query = "";
  if (this.QueryString.Count != 0)
  {
   query = "?";
   for (int i = 0; i <= this.QueryString.Count - 1; i++)
   {
    if (i != 0)
    {
     query += "&";
    }
    query += this.QueryString.GetKey(i) + "=" + this.QueryString.Get(i);
   }
  }
  return query;
 }
 /// <summary>
 /// Get parameter from QueryString
 /// </summary>
 /// <param name="param">Parameter to get</param>
 /// <returns>Parameter Value</returns>
 public string Get(string param)
 {
  return this.QueryString[param];
 }
 /// <summary>
 /// Set QueryString parameter
 /// </summary>
 /// <param name="param">Parameter to set</param>
 /// <param name="value">Value of parameter</param>
 public void Set(string param, string value)
 {
  if (param != string.Empty)
  {
   if (value == string.Empty || value == null)
   {
    this.QueryString.Remove(param);
   }
   else
   {
    this.QueryString[param] = value;
   }
  }
 }
 /// <summary>
 /// Use this method to add a NameValueCollection object to the parent object.
 /// Validation is done to ensure the Key does not already exist in the QueryString object.
 /// </summary>
 /// <param name="collection"></param>
 public void Set(NameValueCollection collection)
 {
  foreach(string key in collection.Keys)
  {
   if(this.QueryString[key] != null)
   {
    this.QueryString.Remove(key);
   }
   this.Set(key,collection[key]);
  }
 }
 /// <summary>
 /// Convert QueryString string to NameValueCollection
 /// http://groups.google.co.uk/groups?hl=en&amp;lr=&amp;ie=UTF-8&amp;safe=off&amp;selm=uyMZ2oaZDHA.652%40tk2msftngp13.phx.gbl
 /// </summary>
 public static NameValueCollection NameValueCollection(string qs)
 {
  NameValueCollection nvc = new NameValueCollection();
  //strip string data before the question mark
  qs = qs.IndexOf('?') > 0 ? qs.Remove(0, qs.IndexOf('?') + 1) : qs;
  Array sqarr = qs.Split("&".ToCharArray());
  for (int i = 0; i < sqarr.Length; i++)
  {
   string[] pairs = sqarr.GetValue(i).ToString().Split("=".ToCharArray());
   nvc.Add(pairs[0], pairs[1]);
  }
  return nvc;
 }
 /// <summary>
 /// Copies a form parameter to the QueryString
 /// </summary>
 /// <param name="param">Form Parameter</param>
 public void FormToQuery(string param)
 {

  this.Set(param, HttpContext.Current.Request.Form[param]);
 }
}

Tags: , ,

1 comment:

LeviRosol said...

Made another change to the helper you put together.

I ran into an issue where i needed a port number to be maintained in the Urls generated by UrlQueryString. For whatever reason, the Url mehtod in .Net does not appear to maintain the port number, so i created a new method that returns you the file and the querystring.

Here's a link to my blog post with code. feel free to use as you wish: http://blogbylevi.iveldesigns.com/archive/2005/05/16/214.aspx