Here's a totally different solution for you:
Create classes derived from System.Web.UI.Page that have the QueryString parameters as properties. Also, using a utility function (see ConvertType, below), you don't need to do too much to get the data out of the QueryString. Lastly, inside those derived classes, define a static inner class that holds constants that are the names of the QueryString parameters so that you don't need to reference any magic values anywhere.
I usually define a base page class for my project, which makes it a convenient place to do common things that happen on all pages, as well as a few utility functions:
public class MyBasePage : System.Web.UI.Page
{
public T GetQueryStringValue<T>(
string value,
T defaultValue,
bool throwOnBadConvert)
{
T returnValue;
if (string.IsNullOrEmpty(value))
return defaultValue;
else
returnValue = ConvertType<T>(value, defaultValue);
if (returnValue == defaultValue && throwOnBadConvert)
// In production code, you'd want to create a custom Exception for this
throw new Exception(string.Format("The value specified '{0}' could not be converted to type '{1}.'", value, typeof(T).Name));
else
return returnValue;
}
// I usually have this function as a static member of a global utility class because
// it's just too useful to only have here.
public T ConvertType<T>(
object value,
T defaultValue)
{
Type realType = typeof(T);
if (value == null)
return defaultValue;
if (typeof(T) == value.GetType())
return (T)value;
if (typeof(T).IsGenericType)
realType = typeof(T).GetGenericArguments()[0];
if (realType == typeof(Guid))
return (T)Convert.ChangeType(new Guid((string)value), realType);
else if (realType == typeof(bool))
{
int i;
if (int.TryParse(value.ToString(), out i))
return (T)Convert.ChangeType(i == 0 ? true : false, typeof(T));
}
if (value is Guid && typeof(T) == typeof(string))
return (T)Convert.ChangeType(((Guid)value).ToString(), typeof(T));
if (realType.BaseType == typeof(Enum))
return (T)Enum.Parse(realType, value.ToString(), true);
try
{
return (T)Convert.ChangeType(value, realType);
}
catch
{
return defaultValue;
}
}
}
public class MyPage : MyBasePage
{
public static class QueryStringParameters
{
public const string Age= "age";
}
public int Age
{
get
{
return base.GetQueryStringValue<int>(Request[QueryStringParameters.Age], -1);
}
}
}
Then, in your regular page, in the code behind, it now looks like this:
public partial class MyWebPage : MyPage
{
protected void Page_Load(object sender, EventArgs e)
{
Foo myFoo = new Foo();
Foo.Age = this.Age;
}
}
It makes the code behind classes very clean (as you can see), and it's easily maintainable because all the heavy-lifting is done by two functions (GetQueryStringValue and ChangeType) that are reused in each of the page classes, and everything is type-safe (you'll notice in GetQueryStringValue that you can specify whether the function throws if the value can't be converted or just uses returns default value; both are appropriate at different times, depending on your app).
Furthermore, you can even easily write a VS plugin or CodeSmith script to generate the derived page class quite easily. And there aren't a bunch of delegates and stuff being passed around, which I find new developers have a hard time understanding.