你如何testing你的Request.QueryString variables?

我经常使用Request.QueryString[]variables。

在我的Page_load我经常做这样的事情:

  int id = -1; if (Request.QueryString["id"] != null) { try { id = int.Parse(Request.QueryString["id"]); } catch { // deal with it } } DoSomethingSpectacularNow(id); 

这一切似乎有点笨重和垃圾。 你如何处理你的Request.QueryString[]

下面是一个扩展方法,可以让你编写这样的代码:

 int id = request.QueryString.GetValue<int>("id"); DateTime date = request.QueryString.GetValue<DateTime>("date"); 

它使用TypeDescriptor来执行转换。 根据您的需要,您可以添加一个重载,它采用默认值而不是引发exception:

 public static T GetValue<T>(this NameValueCollection collection, string key) { if(collection == null) { throw new ArgumentNullException("collection"); } var value = collection[key]; if(value == null) { throw new ArgumentOutOfRangeException("key"); } var converter = TypeDescriptor.GetConverter(typeof(T)); if(!converter.CanConvertFrom(typeof(string))) { throw new ArgumentException(String.Format("Cannot convert '{0}' to {1}", value, typeof(T))); } return (T) converter.ConvertFrom(value); } 

用int.TryParse代替try-catch块:

 if (!int.TryParse(Request.QueryString["id"], out id)) { // error case } 

试试这个家伙…

 List<string> keys = new List<string>(Request.QueryString.AllKeys); 

那么你将能够search一个真正容易的string通过…

 keys.Contains("someKey") 

我正在使用一个小帮手方法:

 public static int QueryString(string paramName, int defaultValue) { int value; if (!int.TryParse(Request.QueryString[paramName], out value)) return defaultValue; return value; } 

这个方法允许我以下面的方式从查询string中读取值:

 int id = QueryString("id", 0); 

那么有一件事使用int.TryParse来代替…

 int id; if (!int.TryParse(Request.QueryString["id"], out id)) { id = -1; } 

这假设“不存在”当然应该有“不是一个整数”的结果。

编辑:在其他情况下,当你要使用请求参数作为string时,我认为这是一个好主意,以validation他们的存在。

你也可以使用下面的扩展方法,这样做

 int? id = Request["id"].ToInt(); if(id.HasValue) { } 

//扩展方法

 public static int? ToInt(this string input) { int val; if (int.TryParse(input, out val)) return val; return null; } public static DateTime? ToDate(this string input) { DateTime val; if (DateTime.TryParse(input, out val)) return val; return null; } public static decimal? ToDecimal(this string input) { decimal val; if (decimal.TryParse(input, out val)) return val; return null; } 
 if(!string.IsNullOrEmpty(Request.QueryString["id"])) { //querystring contains id } 

Eeee这是一个业力风险…

我有一个DRY单元可testing的抽象因为,因为有太多的查询stringvariables要保留在一个传统的转换。

下面的代码来自一个实用工具类,它的构造函数需要一个NameValueCollectioninput(this.source)和string数组“keys”,这是因为遗留应用程序相当有机,并且已经开发了几种不同string作为潜在input键的可能性。 不过,我喜欢可扩展性。 此方法检查密钥的集合,并以所需的数据types返回它。

 private T GetValue<T>(string[] keys) { return GetValue<T>(keys, default(T)); } private T GetValue<T>(string[] keys, T vDefault) { T x = vDefault; string v = null; for (int i = 0; i < keys.Length && String.IsNullOrEmpty(v); i++) { v = this.source[keys[i]]; } if (!String.IsNullOrEmpty(v)) { try { x = (typeof(T).IsSubclassOf(typeof(Enum))) ? (T)Enum.Parse(typeof(T), v) : (T)Convert.ChangeType(v, typeof(T)); } catch(Exception e) { //do whatever you want here } } return x; } 

我实际上有一个实用工具类,它使用generics来“包装”会话,为我做的所有“咕噜工作”,我也有几乎相同的工作与QueryString值。

这有助于删除(通常很多)检查的代码重复。

例如:

 public class QueryString { static NameValueCollection QS { get { if (HttpContext.Current == null) throw new ApplicationException("No HttpContext!"); return HttpContext.Current.Request.QueryString; } } public static int Int(string key) { int i; if (!int.TryParse(QS[key], out i)) i = -1; // Obviously Change as you see fit. return i; } // ... Other types omitted. } // And to Use.. void Test() { int i = QueryString.Int("test"); } 

注意:

这显然是使用静态,有些人不喜欢,因为它可以影响testing代码的方式..你可以很容易地重构成基于实例和任何接口你需要的东西。我只是认为静态的例子是最轻的。

希望这有助于思考。

我有每个function(实际上是一个小类,有很多静态):

  • GetIntegerFromQuerystring(val)
  • GetIntegerFromPost(val)
  • ....

如果失败它返回-1( 这对我来说几乎总是可以的,我也有一些负数的其他函数 )。

 Dim X as Integer = GetIntegerFromQuerystring("id") If x = -1 Then Exit Sub 

我修改了Bryan Watts的答案,这样如果参数你的问题不存在,并且你指定了一个可为空的types,它将返回null:

 public static T GetValue<T>(this NameValueCollection collection, string key) { if (collection == null) { return default(T); } var value = collection[key]; if (value == null) { return default(T); } var type = typeof(T); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { type = Nullable.GetUnderlyingType(type); } var converter = TypeDescriptor.GetConverter(type); if (!converter.CanConvertTo(value.GetType())) { return default(T); } return (T)converter.ConvertTo(value, type); } 

你现在可以这样做:

 Request.QueryString.GetValue<int?>(paramName) ?? 10;