2010-09-28 22 views
23

बदले मैं एक ASP.NET पृष्ठ क्वेरी स्ट्रिंग में अनेक पैरामीटर लेता है। अब उस पृष्ठ के प्रतिपादन के भीतर, मैं लिंक का एक सेट प्रदर्शित करना चाहता हूं जो उपयोगकर्ता को खोज परिणामों के भीतर विभिन्न पृष्ठों पर कूदने की अनुमति देता है। मैं इसे &page=1 या &page=2 इत्यादि जोड़कर कर सकता हूंएकल URL क्वेरी स्ट्रिंग मान

जहां जटिल हो जाता है यह है कि मैं प्रत्येक पैरामीटर के लिए मूल पृष्ठ से इनपुट क्वेरी स्ट्रिंग को संरक्षित करना चाहता हूं, जिसे मैं बदलने की कोशिश कर रहा हूं। वहाँ यूआरएल अन्य घटकों द्वारा इस्तेमाल किया और मूल्य मैं बदलने के लिए कोशिश कर रहा हूँ में अन्य पैरामीटर हो सकता है पहले से परिभाषित कर सकते हैं या नहीं किया जा सकता:

search.aspx?q=123&source=WebSearch&page=1&Theme=Blue 

इस मामले में परिणामों के अगले पृष्ठ के लिए एक लिंक उत्पन्न करने के लिए, मैं शेष क्वेरी स्ट्रिंग को अपरिवर्तित छोड़कर page=1page=2 को बदलना चाहता हूं।

क्या ऐसा करने का कोई अंतर्निहित तरीका है, या क्या मुझे मैन्युअल रूप से सभी स्ट्रिंग पार्सिंग/पुनः संयोजन करने की आवश्यकता है?

उत्तर

0

URIBuilder उपयोग विशेष रूप से link text क्वेरी संपत्ति

मुझे विश्वास है कि आपको क्या चाहिए होता है।

+0

UriBuilder मुझे अनुरोध uRL का संपूर्ण क्वेरी घटक बाहर परिवर्तित करने देता है, मुझे क्या करना कोशिश कर रहा हूँ बदलने/यूआरएल के भीतर एक विशिष्ट क्वेरी पैरामीटर जोड़ना है। – star

5

इस QueryStringBuilder helper class का उपयोग करके आप वर्तमान QueryString हड़पने और एक मौजूदा मुख्य/मान जोड़े को बदलने के लिए Add विधि कॉल कर सकते हैं ...

//before: "?id=123&page=1&sessionId=ABC" 
string newQueryString = QueryString.Current.Add("page", "2"); 
//after: "?id=123&page=2&sessionId=ABC" 
+0

अच्छा संसाधन। धन्यवाद! – Mark1270287

+0

नया संस्करण प्रारूप का उपयोग करता है: स्ट्रिंग newQueryString = QueryString.Current.Add ("पृष्ठ", "2")। ToString(); – Mark1270287

51

आप QueryString सीधे संशोधित नहीं कर सकते, क्योंकि यह केवल पढ़ने के लिए है। आपको मूल्य प्राप्त करने, उन्हें संशोधित करने, फिर उन्हें एक साथ वापस रखने की आवश्यकता होगी। एक NameValueCollection (वास्तव में यह वास्तव में एक HttpValueCollection जो परिणाम, as I mention in an answer to another question encodes रिटर्न)

var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString()); 
nameValues.Set("page", "2"); 
string url = Request.Url.AbsolutePath; 
string updatedQueryString = "?" + nameValues.ToString(); 
Response.Redirect(url + updatedQueryString); 

ParseQueryString method रिटर्न: इस प्रयास करें। फिर आप मान को अपडेट करने के लिए Set विधि का उपयोग कर सकते हैं। आप मूल्य को हटाने के लिए नया, या Remove जोड़ने के लिए Add विधि का भी उपयोग कर सकते हैं। अंत में, NameValueCollection नाम पर ToString() पर कॉल करने से नाम name1=value1&name2=value2 क्वेरीस्ट्रिंग तैयार प्रारूप में नाम मान जोड़े लौटाता है। एक बार जब आप इसे यूआरएल में जोड़ दें और रीडायरेक्ट करें।

वैकल्पिक रूप से, आप एक नया कुंजी जोड़ सकते हैं, या किसी मौजूदा संशोधित करने, इंडेक्सर का उपयोग कर:

nameValues["temp"] = "hello!"; // add "temp" if it didn't exist 
nameValues["temp"] = "hello, world!"; // overwrite "temp" 
nameValues.Remove("temp"); // can't remove via indexer 

आप NameValueCollection वर्ग का उपयोग करने के एक using System.Collections.Specialized; जोड़ने की जरूरत हो सकती है।

+0

असल में आप इसे सीधे सेट कर सकते हैं, प्रतिबिंब आपको इसे संशोधित करने देता है। हालांकि मैं व्यक्तिगत रूप से एक एनवीसी का उपयोग करने के साथ सहमत हूं। – annakata

+0

@annakata बस अपनी प्रतिक्रिया पढ़ें। दिलचस्प दृष्टिकोण, पहली बात नहीं जो दिमाग में आती है। –

+0

ToString विधि के साथ एक और समस्या है। यह गलत मानों को कई मानों से संभालता है। अल्पविराम से अलग सूची बनाने के बजाय, यह जोड़े कुंजी = मान डुप्लिकेट करें। उदाहरण के लिए यदि आपने मान मान 1 के साथ दो बार प्रवेश पैरामीटर जोड़ा है, तो मूल्य 2 आपको param = value1, value2 के बजाय परिणाम param = value1 और param = value2 मिलेगा। – Stoune

12

आप पुनर्निर्देशन के सभी उपरि के बिना ऐसा कर सकते हैं (जो असंगत नहीं है)। कम से कम नेट कोर में

// reflect to readonly property 
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 

// make collection editable 
isReadOnly.SetValue(this.Request.QueryString, false, null); 

// remove 
this.Request.QueryString.Remove("foo"); 

// modify 
this.Request.QueryString.Set("bar", "123"); 

// make collection readonly again 
isReadOnly.SetValue(this.Request.QueryString, true, null); 
+0

यह एक बहुत अच्छा समाधान है कि मुझे यकीन नहीं था कि यह काम करेगा, लेकिन मेरे लिए चाल है। मैं वास्तव में प्रतिक्रिया नहीं दे सका। प्रत्यक्ष रूप से मेरे वास्तुकला के आधार पर और इस दृष्टिकोण से बच सकता है। धन्यवाद! –

+0

मुझे त्रुटि मिल रही है "'PropertyInfo' 'प्रतिबिंब' में एक प्रकार है और अभिव्यक्ति के रूप में उपयोग नहीं किया जा सकता है।" – jbyrd

0

यह सुंदर मनमाना है,: मेरी निजी पसंद एक NameValueCollection जो एक क्वेरी स्ट्रिंग वास्तव में है के साथ काम करने के लिए, लेकिन प्रतिबिंब का उपयोग कर रहा है।और यह सब asp-all-route-data

करने पर निर्भर करता है निम्न तुच्छ उदाहरण पर विचार ("paginator" दृश्य मॉडल से लिया मैं लगभग हर परियोजना में उपयोग करें):

public class SomeViewModel 
{ 

    public Dictionary<string, string> NextPageLink(IQueryCollection query) 
    { 
     /* 
     * NOTE: how you derive the "2" is fully up to you 
     */ 
     return ParseQueryCollection(query, "page", "2"); 
    } 

    Dictionary<string, string> ParseQueryCollection(IQueryCollection query, string replacementKey, string replacementValue) 
    { 
     var dict = new Dictionary<string, string>() 
     { 
      { replacementKey, replacementValue } 
     }; 

     foreach (var q in query) 
     { 
      if (!string.Equals(q.Key, replacementKey, StringComparison.OrdinalIgnoreCase)) 
      { 
       dict.Add(q.Key, q.Value); 
      } 
     } 

     return dict; 
    } 
} 

फिर अपने दृश्य में उपयोग करने के लिए, बस पारित विधि Context.Request से वर्तमान अनुरोध क्वेरी संग्रह:

<a asp-all-route-data="@Model.NextPageLink(Context.Request.Query)">Next</a> 
संबंधित मुद्दे