2008-12-08 18 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); 
} 
+0

मुझे यह काम करने के लिए लाइन 15 और 17 को बदलना पड़ा: var कनवर्टर = टाइपडिस्क्रिप्टर। गेट कनवर्टर (टाइपोफ (टी)); अगर (! कनवर्टर.कैनकॉन्टरटॉ (मूल्य।GetType()) –

+0

धन्यवाद ब्रायन –

+0

हाय, यह बहुत अच्छा है हालांकि यह नलिकाओं के साथ काम नहीं करता है, उदाहरण के लिए int? टाइप कनवर्टर में एक बग हो सकता है? यदि आप रुचि रखते हैं तो परीक्षण का मूल्य। – bplus

32

उपयोग int.TryParse बजाय कोशिश कैच ब्लॉक से छुटकारा पाने के:

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

धन्यवाद साथी, कि टिप की तरह मैं जरूरत है: डी – inspite

+0

हाँ, TryParse बहुत अच्छा है! –

+0

उत्कृष्ट विचार ... –

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

क्या होगा यदि उपयोगकर्ता पेज.aspx की तरह गड़बड़ कर देता है? Id = 123 to page.aspx? 1234 –

+0

@DamienJoe तो उपयोगकर्ता को 404 मिलना चाहिए। – Dan

+0

@DamienJoe: उपयोगकर्ता क्वेरी स्ट्रिंग टाइप क्यों करेगा मैन्युअल रूप से पैरामीटर, क्या वे केवल उन (अच्छी तरह से गठित) लिंक पर क्लिक नहीं कर रहे हैं जिन्हें आप उन्हें देते हैं? –

1

मैं प्रत्येक के लिए कार्य करता है (वास्तव में यह है, एक छोटा सा वर्ग है स्टैटिक्स के बहुत सारे के साथ) है:

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

यह रिटर्न - 1 अगर विफल रहता है (जो मेरे लिए लगभग हमेशा ठीक है, मेरे पास है नकारात्मक संख्याओं के साथ-साथ) के लिए कुछ अन्य कार्य।

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

मैं एक छोटे से सहायक विधि का उपयोग कर रहा हूँ कर्म जोखिम ...

मेरे पास एक DRY इकाई-परीक्षण योग्य अमूर्तता है, क्योंकि, बहुत सारे क्वेरीस्ट्रिंग चर थे एक विरासत रूपांतरण में रखने के लिए है।

नीचे दिया गया कोड एक उपयोगिता वर्ग से है जिसका कन्स्ट्रक्टर को नामवैल्यूलेक्शन इनपुट (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; 
} 
+0

कक्षा पुस्तकालय में रखने के लिए एक सहायक विधि के लिए क्या एक अच्छा विचार है! –

+0

हाँ मुझे यह भी पसंद है; डी – inspite

+0

वास्तव में विधि के अंदर एक त्रुटि है। "Request.QueryString" के बजाय यह "HttpContext.Current.Request.QueryString" होना चाहिए। – M4N

1

Eeee यह एक है:

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

इस विधि मुझे निम्नलिखित तरीके से क्वेरी स्ट्रिंग से मानों को पढ़ सकते:

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

यह मेरे द्वारा उपयोग किए जाने वाले जैसा ही है .. :) –

1

मैं वास्तव में एक उपयोगिता वर्ग जेनेरिक्स का उपयोग करता है "रैप" करने के लिए सत्र, जो मेरे लिए "घुरघुराना काम" के सभी करता है, मैं भी कुछ 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"); 
} 

नोट:

यह स्पष्ट रूप से जो कुछ लोगों क्योंकि जिस तरह से यह परीक्षण कोड को प्रभावित कर सकता की पसंद नहीं है स्टैटिक्स के उपयोग, बनाता है .. आप आसानी से कर सकते हैं उदाहरणों और किसी भी इंटरफेस के आधार पर काम करने वाली किसी चीज में रिफैक्टर .. मुझे लगता है कि स्टेटिक्स उदाहरण सबसे हल्का है।

आशा है कि इससे विचार के लिए भोजन/मदद मिलती है।

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; 
} 
+0

यह बहुत अच्छा है मुझे यह पसंद है। धन्यवाद – inspite

+1

हम इस तकनीक का उपयोग करते हैं, लेकिन गैर-शून्य संस्करण हैं, उदा। "int toInt (int defaultValue = 0)" और "int? AsInt()" – Jerph

+0

@ जेर्फ़ का सुझाव बहुत अच्छा है, लेकिन आप उपरोक्त का उपयोग 'अनुरोध ["आईडी"] के रूप में भी कर सकते हैं। ToInt()। GetValueOrDefault (0) एक ही प्रभाव प्राप्त करने के लिए। –

1

मैं ब्रायन वत्स 'जवाब संशोधित इतना है कि यदि परम अपने पूछने मौजूद नहीं है और आप एक नल निर्दिष्ट किया है प्रकार यह शून्य वापस आ जाएगी:

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; 
+0

'Int32Converter' 'System.String' को 'System.Nullable'1' में परिवर्तित करने में असमर्थ है [[System.Int32, mscorlib, संस्करण = 2.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = b77a5c561934e089]] '। – Soonts

+1

टिप्पणी के लिए धन्यवाद @Sunts, मैंने कोड को Nullables को संभालने के लिए थोड़ा बदल दिया। – W3Max

19

इस दोस्त का प्रयास करें ...

+०१२३५१६४१०६१
List<string> keys = new List<string>(Request.QueryString.AllKeys); 

तो फिर तुम एक स्ट्रिंग असली आसान के माध्यम से के लिए पुरुष खोज करने के लिए सक्षम हो जाएगा ...

keys.Contains("someKey") 
+1

वाह। हाँ। बहुत खुबस। +1 – Brandon

+1

बढ़िया! आसान, तेज़ और मुझे क्या चाहिए! +1 सरल मुझे जिस तरह से पसंद है। – Mixxiphoid

संबंधित मुद्दे