2008-12-08 168 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")