这里有一个完全不同的解决方案:
创建从具有 QueryString 参数作为属性的 System.Web.UI.Page 派生的类。此外,使用实用程序函数(请参阅下面的 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 脚本来非常轻松地生成派生页面类。而且没有一堆委托和东西被传递,我发现新开发人员很难理解。