Вот вам совершенно другое решение:
Создание классов, производных от System.Web.UI.Page, которые имеют параметры QueryString в качестве свойств. Кроме того, используя служебную функцию (см. ConvertType ниже), вам не нужно делать слишком много, чтобы получить данные из QueryString. Наконец, внутри этих производных классов определите статический внутренний класс, который содержит константы, которые являются именами параметров QueryString, чтобы вам не приходилось ссылаться ни на какие магические значения.
Я обычно определяю базовый класс страниц для своего проекта, что делает его удобным местом для выполнения общих задач, которые происходят на всех страницах, а также для нескольких служебных функций:
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);
}
}
}
Тогда на вашей обычной странице, в коде позади, теперь это выглядит так:
public partial class MyWebPage : MyPage
{
protected void Page_Load(object sender, EventArgs e)
{
Foo myFoo = new Foo();
Foo.Age = this.Age;
}
}
Это делает код за классами очень чистым (как вы можете видеть), и его легко обслуживать, потому что вся тяжелая работа выполняется двумя функциями (GetQueryStringValue и ChangeType), которые повторно используются в каждом из классы страницы, и все это безопасно для типов (вы заметите в GetQueryStringValue, что вы можете указать, будет ли функция генерировать, если значение не может быть преобразовано, или просто использует возвращаемое значение по умолчанию; оба варианта подходят в разное время, в зависимости от вашего приложение).
Более того, вы даже можете легко написать плагин VS или скрипт CodeSmith, чтобы довольно легко сгенерировать производный класс страницы. И там не будет куча делегатов и прочего, что, как мне кажется, новым разработчикам трудно понять.