Skip to main content

Passing Parameters from One Page to Another

Introduction Passing parameters from one page to another is a very common task in Web development. Granted, its importance and frequency has faded a bit with ASP.NET's inherent preference for postback forms, but regardless, there are still many situations in which you need to pass data from one Web page to another. One of the simplest and most efficient ways of passing parameters among pages is to use the querystring. Unfortunately, packing data into the querystring via string manipulations can quickly lead to cumbersome and often difficult to maintain code, especially as the parameter list grows. Consider the following C# code to pass a number of parameters from on the querystring:

string URL = "Page2.aspx?FirstName=" + txtFirstName.Text + "&MiddleName=" + txtMiddleName.Text + "&LastName=" + txtLastName.LastName + "&DOB=" + Session["txtDOB"].ToString() + "&State=" + Request.Form.Get("hiddenState"); Response.Redirect(URL);

This code is somewhat unclear, making it hard to see at a glance what the variable names on the querystring are, and what values are being passed for each variable. Further, changes to variables that are passed are more cumbersome and prone to error than they need to be.

Starting from the Base... Initially I created just a simple class for passing parameters through the querystring, which met my needs at the time. But thinking more about my class, I realized that the high-level aim was to pass data from one page to another - why should I limit it to using the querystring? I decided to take a step back and define the functionality needed for passing data from one page to another, ignoring the actual implementation details.

In order to pass data from one page to another I reasoned that the following would be needed:

  • The URL of the page that is to receive the data
  • The name/value pairs of the data to pass
  • A method that, when called, will pass the supplied data to the specified page
Similarly, the page that received the data needed a means to:
  • Extract the value for a name/value pair
  • Enumerate all values in the parameter collection
Therefore, I started by creating a base class with the core functionality required. I named this class ParameterPasserTester and made it abstract, meaning that it had to be extended. My aim for providing a concrete implementation - using the querystring or Session variables - was to create classes that were derived from ParameterPasserTester and included the code to work with the particular, concrete technique.

The following is the complete code for the ParameterPasserTester base class. (The complete working code and a sample are available at the end of this article.)


public abstract class BaseParameterPasser
{
 private string url = string.Empty;

 public BaseParameterPasser()
 {
  if (HttpContext.Current != null)
   url = HttpContext.Current.Request.Url.ToString();
 }

 public BaseParameterPasser(string Url)
 {
  this.url = Url;
 }

 public virtual void PassParameters()
 {
  if (HttpContext.Current != null)
   HttpContext.Current.Response.Redirect(Url);
 }

 public string Url
 {
  get
  {
   return url;
  }
  set
  {
   url = value;
  }
 }

 public abstract string this[string name]
 {
  get;
  set;
 }

 public abstract ICollection Keys
 {
  get;
 }
}

As the code shows, this base class has a Url property that indicates the page the data should be passed to. It also has two abstract properties: Keys, which returns a collection of the parameter keys, and an indexer property that allows the parameters to be added and retrieved using syntax like myParameterPasser[name] = value. Furthermore, two constructors are provided, one that you can specify the URL directly, and one that uses the current page's URL as the redirect URL. Finally, there's the PassParameters() method that, when called, sends the user to the specified page, passing the parameters.

Passing Data Through the QueryString Armed with this base class, creating a class to pass parameters through the querystring is a breeze - I just simply created a class that derived from BaseParameterPasser and overrided the necessary fields. The code for this new class, UrlParameterPasser, is shown below:


public class UrlParameterPasser : BaseParameterPasser
{
  private SortedList localQueryString = null;

  public UrlParameterPasser() : base() {}     
  public UrlParameterPasser(string Url) : base(Url) {}

  public override void PassParameters()
  {
     // add parameters, if any exist
     if (localQueryString.Count > 0)
     {
        // see if we need to add the ?
        if (base.Url.IndexOf("?") == -1)
           base.Url += "?";
        else
           base.Url += "&";

        bool firstOne = true;
        foreach (DictionaryEntry o in localQueryString)
        {
           if (!firstOne)
              base.Url += "&";
           else
              firstOne = false;

           base.Url += string.Concat(
                       HttpContext.Current.Server.UrlEncode(o.Key.ToString()),
                       "=",
                       HttpContext.Current.Server.UrlEncode(o.Value.ToString()));
        }
     }

     base.PassParameters();
  }

  public override string this[string name]
  {
     get
     {
        if (localQueryString == null)
        {
           if (HttpContext.Current != null)
              return HttpContext.Current.Request.QueryString[name];
           else
              return null;
        }
        else
           return localQueryString[name].ToString();
     }
     set
     {
        if (localQueryString == null)
           localQueryString = new SortedList();

        // add if it is new, or replace the old value
        if ((localQueryString[name]) == null)
           localQueryString.Add(name, value);
        else
           localQueryString[name] = value;
     }
  }

  public override ICollection Keys
  {
     get
     {
        if (localQueryString == null)
        {
           if (HttpContext.Current != null)
              return HttpContext.Current.Request.QueryString.Keys;
           else
              return null;
        }
        else
           return localQueryString.Keys;
     }
  }
}

As you can see, when adding parameters to the data to be passed, a SortedList is used; on the flip-side, when the page that has received the parameters is reading from the parameter list, the Request.QueryString collection is used. The PassParameters() method, which is called by the sending page to initiate the call to the receiving page, builds up the URL by enumerating the parameter values and packing them into the querystring.

With this class, the code for calling one page from another passing values in a querystring changes to very readable code:


// Pass textbox values to ReceiveQueryString.aspx
UrlParameterPasser urlWrapper = new UrlParameterPasser("ReceiveQueryString.aspx");

// Add some values
urlWrapper["name"] = name.Text;
urlWrapper["age"] = age.Text;

// Redirect to the page, passing the parameters in the querystring
urlWrapper.PassParameters();

You will notice that this code is significantly easier to read, clearer in what it is doing, and will therefore be easier to maintain. But, better still, the code is going to be less prone to typing errors, such as forgetting an ampersand or putting a quote in the wrong place. To complete the hand-off, I use the same class on the target page to pull off these parameters values. Reading them back is just as simple:


// Receive the parameters
UrlParameterPasser urlWrapper = new UrlParameterPasser();
string myName = urlWrapper["name"];
int myAge = Convert.ToInt32(urlWrapper["age"]);

Care to Use Session Variables? In addition to the UrlParameterPasser class there's also a SessionParameterPasser that is syntactically equivalent, but uses Session variables as the backing store as opposed to the querystring collection. This class is fairly simple and straightforward, and included in this article's download.(source-4guysfromrolla)

Comments

Popular posts from this blog