2008-12-08 79 views
49

我经常使用Request.QueryString[]变量。你如何测试你的Request.QueryString []变量?

在我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[]

回答

51

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

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

它利用TypeDescriptor来执行转换。根据您的需求,您可以添加一个重载需要一个默认值,而不是抛出一个异常:

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); 
} 
32

使用int.TryParse而不是摆脱try-catch块的:

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

谢谢哥们,这就是我所需要的一种提示的:d – inspite 2008-12-08 14:42:32

+0

呀,的TryParse是伟大的! – 2008-12-08 15:05:28

+0

好主意...... – 2012-02-07 11:39:37

10

好一所件事用int.TryParse,而不是...

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

这假定“不当然“当然应该有”不是整数“的结果。

编辑:在其他情况下,当你打算使用请求参数作为字符串时,我认为确认它们存在是一个好主意。

4
if(!string.IsNullOrEmpty(Request.QueryString["id"])) 
{ 
//querystring contains id 
} 
+0

如果用户像page.aspx?id = 123到page.aspx?1234 – 2012-02-07 11:38:42

+0

@DamienJoe那样会出现什么情况那么用户应该得到一个404。 – Dan 2013-05-17 13:23:09

+0

@DamienJoe:为什么用户输入查询字符串手动输入参数,不应该只是点击你给他们的(格式良好的)链接? – 2013-10-22 16:23:17

1

我有每个功能(实际上这是一个小班,有很多静态的):

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

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

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

我使用了一个小帮手方法:

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

这种方法可以让我以下面的方式读取查询字符串值:

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

辅助方法放入类库是个好主意! – 2008-12-08 14:56:38

+0

是的,我也喜欢; D – inspite 2008-12-08 14:59:05

1

èéêë这是一个业障风险...

我有一个DRY单元可测试的抽象因为,因为有太多的查询字符串变量s继续进行传统转换。

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

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; 
} 
1

其实我有一个使用泛型“包装”会议,这确实所有的“繁重的工作”为我的一个实用工具类,我也有一些与查询字符串值的工作几乎相同。

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

例如:

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"); 
} 

注:

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

希望这可以帮助/提供思考。

9

您可以使用下面以及扩展方法,做这样的

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; 
} 
1

我修改布莱恩瓦特的答案,这样,如果帕拉姆您的要价不存在,并已指定了可空键入将返回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; 
19

试试这个家伙......

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

然后你就可以搜索字符串真正的轻松通过家伙......

keys.Contains("someKey")