2009-02-22 16 views
7

आप अपनी क्वेरी स्ट्रिंग मान पार्स करने के लिए एक अच्छा और साफ रास्ता तलाश किया गया है, मैं इस के साथ आ गए हैं:सी # ASP.NET QueryString पार्सर

/// <summary> 
    /// Parses the query string and returns a valid value. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="key">The query string key.</param> 
    /// <param name="value">The value.</param> 
    protected internal T ParseQueryStringValue<T>(string key, string value) 
    { 
     if (!string.IsNullOrEmpty(value)) 
     { 
      //TODO: Map other common QueryString parameters type ... 
      if (typeof(T) == typeof(string)) 
      { 
       return (T)Convert.ChangeType(value, typeof(T)); 
      } 
      if (typeof(T) == typeof(int)) 
      { 
       int tempValue; 
       if (!int.TryParse(value, out tempValue)) 
       { 
        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " + 
                   "'{1}' is not a valid {2} type.", key, value, "int")); 
       } 
       return (T)Convert.ChangeType(tempValue, typeof(T)); 
      } 
      if (typeof(T) == typeof(DateTime)) 
      { 
       DateTime tempValue; 
       if (!DateTime.TryParse(value, out tempValue)) 
       { 
        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " + 
                 "'{1}' is not a valid {2} type.", key, value, "DateTime")); 
       } 
       return (T)Convert.ChangeType(tempValue, typeof(T)); 
      } 
     } 
     return default(T); 
    } 

मैं हमेशा ऐसा ही कुछ करना चाहते थे है और अंत में यह बेहतर सराहना कर रहे हैं बनाने के लिए मिल गया है यह सही ... कम से कम मुझे ऐसा लगता है ...

कोड आत्म व्याख्यात्मक होना चाहिए ...

कोई टिप्पणी या सुझाव।

+0

हो सकता है कि आप इसे पहले अपने कोड स्टैक से पहले संभाल लें, लेकिन याद रखें कि एक कुंजी में क्वेरीस्ट्रिंग में एकाधिक मान हो सकते हैं, यानी x = 1,2,3 – jro

+0

@jro मैं एकाधिक मान केस को अमान्य मानता हूं क्योंकि जहां तक क्वेरीस्ट्रिंग का केवल एक मान है, "1,2,3" की एक स्ट्रिंग, इसे किसी भी रूप में पार्स करना और बात सही नहीं होगी। ParseExact/TryParseExact के लिए – rtpHarry

उत्तर

5

यह देखते हुए कि आप केवल तीन अलग-अलग प्रकारों को संभालते हैं, मैं इसके बजाय तीन अलग-अलग तरीकों का सुझाव दूंगा - जेनेरिक तरीके सर्वोत्तम होते हैं जब वे प्रकार की बाधाओं द्वारा अनुमत हर प्रकार के तर्क के साथ अच्छी तरह से काम करते हैं।

इसके अलावा, मैं दृढ़ता से int के लिए सुझाव है कि और DateTime आप उपयोग करना संस्कृति निर्दिष्ट - यह वास्तव में संस्कृति सर्वर में होने वाला पर निर्भर नहीं करना चाहिए (आप की संस्कृति का अनुमान लगाना कोड है, तो। उपयोगकर्ता, आप इसके बजाय इसका उपयोग कर सकते हैं।) अंत में, मैं DateTime प्रारूपों के एक अच्छी तरह से निर्दिष्ट सेट का समर्थन करने का सुझाव देता हूं, जो डिफ़ॉल्ट रूप से TryParse समर्थन करता है। (मैं काफी हमेशा उपयोग ParseExact/TryParseExact बजाय Parse/TryParse।)

ध्यान दें कि स्ट्रिंग संस्करण वास्तव में कुछ भी करने को, (की जरूरत नहीं है यह देखते हुए कि value पहले से ही एक स्ट्रिंग है, हालांकि अपने वर्तमान कोड धर्मान्तरित " "null पर, जो आप चाहते हैं या नहीं हो सकता है)।

+0

+1 विशेष रूप से आप प्रारूपों की एक सरणी पास कर सकते हैं। – Richard

1

ऐसा लगता है कि आप बहुत सारे प्रकार के असंगत प्रकार के रूपांतरण कर रहे हैं। TempValue चर आपके द्वारा लौटने की कोशिश कर रहे प्रकार के प्रकार का नेतृत्व कर रहे हैं। इसी प्रकार स्ट्रिंग केस में मान पहले से ही एक स्ट्रिंग है इसलिए इसे इसके बजाय वापस कर दें।

2

अपने आवेदन में मैं निम्नलिखित समारोह का उपयोग कर रहे: -

public static class WebUtil 
{ 
    public static T GetValue<T>(string key, StateBag stateBag, T defaultValue) 
    { 
     object o = stateBag[key]; 

     return o == null ? defaultValue : (T)o; 
    } 
} 

डिफ़ॉल्ट रूप से आवश्यक लौटा दिया जाता है, तो पैरामीटर की आपूर्ति नहीं की गई है, प्रकार DefaultValue से अनुमान लगाया जाता है और कास्टिंग अपवाद आवश्यक के रूप में उठाया जाता है ।

प्रयोग इस प्रकार है: -

var foo = WebUtil.GetValue("foo", ViewState, default(int?)); 
34

पार्स करने के लिए (यदि आप न प्रकार रूपांतरण करना चाहते हैं) एक आसान तरीका

HttpUtility.ParseQueryString(queryString); 

आप

URL से क्वेरी स्ट्रिंग निकाल सकते हैं है
new Uri(url).Query 
+4

यह केवल तभी काम करता है जब यूआरएल एक पूर्ण यूआरएल है। यदि आपके पास एक सापेक्ष यूआरएल है, तो उरी का प्रश्न सदस्य समर्थित नहीं है। – jrwren

3

मैंने दृढ़ता से टाइप किए गए मानों के लिए क्वेरीरीस्ट्रिंग को पार्स करने के लिए निम्न विधि लिखी है:

public static bool TryGetValue<T>(string key, out T value, IFormatProvider provider) 
{ 
    string queryStringValue = HttpContext.Current.Request.QueryString[key]; 

    if (queryStringValue != null) 
    { 
     // Value is found, try to change the type 
     try 
     { 
      value = (T)Convert.ChangeType(queryStringValue, typeof(T), provider); 
      return true; 
     } 
     catch 
     { 
      // Type could not be changed 
     } 
    } 

    // Value is not found, return default 
    value = default(T); 
    return false; 
} 

प्रयोग उदाहरण:

int productId = 0; 
bool success = TryGetValue<int>("ProductId", out productId, CultureInfo.CurrentCulture); 

?productId=5 की एक क्वेरी स्ट्रिंग bool सच हो सकता है और int productId 5 के बराबर होता है।

?productId=hellobool झूठा हो सकता है और int productId की एक क्वेरी स्ट्रिंग 0.

बराबर होता ?noProductId=notIncludedbool झूठा हो सकता है और int productId की एक क्वेरी स्ट्रिंग 0.

0

बराबर हैं Ronalds answer के आधार पर मैं अद्यतन किया है के लिए मेरी खुद की क्वेरीस्ट्रिंग पार्सिंग विधि। जिस तरह से मैं इसका उपयोग करता हूं वह इसे पृष्ठ ऑब्जेक्ट पर एक विस्तार विधि के रूप में जोड़ना है, इसलिए मेरे लिए क्वेरीस्ट्रिंग मानों और प्रकारों की जांच करना आसान है और यदि पृष्ठ अनुरोध मान्य नहीं है तो पुनर्निर्देशित करें।

विस्तार विधि इस प्रकार है:

public static class PageHelpers 
{ 
    public static void RequireOrPermanentRedirect<T>(this System.Web.UI.Page page, string QueryStringKey, string RedirectUrl) 
    { 
     string QueryStringValue = page.Request.QueryString[QueryStringKey]; 

     if(String.IsNullOrEmpty(QueryStringValue)) 
     { 
      page.Response.RedirectPermanent(RedirectUrl); 
     } 

     try 
     { 
      T value = (T)Convert.ChangeType(QueryStringValue, typeof(T)); 
     } 
     catch 
     { 
      page.Response.RedirectPermanent(RedirectUrl); 
     } 
    } 
} 

यह मैं जैसे कार्य करने के देता है निम्नलिखित:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Page.RequireOrPermanentRedirect<int>("CategoryId", "/"); 
} 

मैं तो मेरे कोड के बाकी लिखने और अस्तित्व और सही पर भरोसा कर सकते क्वेरीस्ट्रिंग आइटम का प्रारूप इसलिए मुझे इसे हर बार जांचना नहीं है जब मैं इसे एक्सेस करना चाहता हूं।

नोट: यदि आप तो पूर्व .net 4 उपयोग कर रहे हैं आप भी चाहते हैं निम्नलिखित RedirectPermanent विस्तार विधि:

public static class HttpResponseHelpers 
{ 
    public static void RedirectPermanent(this System.Web.HttpResponse response, string uri) 
    { 
     response.StatusCode = 301; 
     response.StatusDescription = "Moved Permanently"; 
     response.AddHeader("Location", uri); 
     response.End(); 
    } 
} 
2

यह एक पुरानी जवाब है, लेकिन मैं किया है निम्नलिखित:

  string queryString = relayState.Split("?").ElementAt(1); 
      NameValueCollection nvc = HttpUtility.ParseQueryString(queryString); 
संबंधित मुद्दे