कैसे एक NameValueCollection .NET में क्वेरी स्ट्रिंग पार्स करने के लिए


186

मैं एक स्ट्रिंग को पार्स करना चाहूंगा जैसे कि p1=6&p2=7&p3=8NameValueCollection

जब आपके पास Page.Requestऑब्जेक्ट तक पहुंच नहीं है, तो ऐसा करने का सबसे सुरुचिपूर्ण तरीका क्या है ?

जवाबों:


356

इसके लिए एक अंतर्निहित .NET उपयोगिता है: HttpUtility.ParseQueryString

// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)

आप बदलना पड़ सकता है querystringके साथ new Uri(fullUrl).Query


26
उमर, यह मेरे लिए ASP.NET 4 पर काम नहीं करता था, इसने " paral " के बजाय " stackoverflow.com?para " की एक कुंजी लौटा दी । इसलिए मैं HttpUtility.ParseQueryString (नई Uri (fullUrl) .Query) का उपयोग कर रहा हूं जो मेरे लिए सही ढंग से काम करता है।
माइकल

2
qscoll ["p1"], qscoll ["P2"] और qscoll ["p3"]
SMUsamaShah

5
ParseQueryString डेस्कटॉप अनुप्रयोग में उपयोग करने के लिए वास्तव में खराब विचार है, क्योंकि यह क्लाइंट प्रोफाइल में शामिल नहीं है; सिर्फ एक सरल विधि का उपयोग करने के लिए क्लाइंट कंप्यूटर पर 100 M अतिरिक्त लाइब्रेरी स्थापित करने के लिए क्यों? हालाँकि, ऐसा लगता है कि Microsoft के पास कोई बेहतर विचार नहीं है। एकमात्र तरीका खुद की विधि को लागू करना है या ओपन सोर्स कार्यान्वयन का उपयोग करना है।
विटाली

2
VASoftOnline: उस स्थिति में आप ParseQueryString के मोनो कार्यान्वयन का उपयोग कर सकते हैं: github.com/mono/mono/blob/master/mcs/class/System.Web/ ... उस के लिए लाइसेंस MIT X11 है: github.com/mono/mono/mono / बूँद / मास्टर / LICENSE
स्व।

3
HttpUtility.ParseQueryStringसिवाय इसके कि मेरी सिफारिश होगी कि HttpUtility.ParseQueryString("&X=1&X=2&X=3")परिणाम के मामले में एक ....X=1,2,3...ही नाम के कई सारे परिमाण असामान्य हैं, लेकिन कंट्रोलर मापदंडों जैसे int [], IEnumerable <int> आदि का समर्थन करने की आवश्यकता है (ऐसे params का उपयोग कई मल्टीबॉक्स के लिए किया जा सकता है) एमएस साइट के अनुसार "एक ही क्वेरी स्ट्रिंग वेरिएबल के कई आवृत्तियों को एक प्रविष्टि में समेकित किया जाता है" देखें । विधि का एक दस्तकारी संस्करण आपका एकमात्र विकल्प हो सकता है
17:15 बजे

43

HttpUtility.ParseQueryString जब तक आप एक वेब ऐप में हैं या System.Web पर निर्भरता सहित कोई बुरा काम नहीं करेंगे। ऐसा करने का एक और तरीका है:

NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
   string[] parts = segment.Split('=');
   if (parts.Length > 0)
   {
      string key = parts[0].Trim(new char[] { '?', ' ' });
      string val = parts[1].Trim();

      queryParameters.Add(key, val);
   }
}

5
आपको यह देखना चाहिए कि क्या पुर्जे.लिफ्टिंग> 1, यह सुनिश्चित करने के लिए कि आप पुर्जे पुकार सकते हैं [1]
अलेक्जेंड्रू पुप्सा सिप

2
अगर कोई मूल्य नहीं है तो क्या होगा? उदाहरण के लिए एक क्वेरी स्ट्रिंग की तरह लग सकता है ?foo=1&barHttpUtilityइसे पार्स करेंगे{ key = null, value = "bar" }
थॉमस लेवेस्क

यह HttpUtility.ParseQueryString की तुलना में बहुत अच्छा है क्योंकि यह मानों को डिकोड नहीं करता है (इसलिए बेस 64 एनकोडेड मान संरक्षित हैं)
CRice

1
वास्तव में, आपको अभी भी उदाहरण और कोड के लिए '=' मान देने की आवश्यकता है = A0SYw34Hj / m ++ lH0s7r0l / yg6GWdymzSCbI2zOn3V4o = में अंतिम '=' वर्ण हटा दिया जाएगा। मैंने '=' का पहला इंडेक्स प्राप्त करने के लिए आपके कोड का हिस्सा फिर से लिखा है और इसे ठीक करने के लिए (स्प्लिट का उपयोग करने के बजाय) कुंजी और मान को प्रतिस्थापित किया है।
1

28

System.Web पर स्वीकृत उत्तर की निर्भरता के कारण बहुत सारे उत्तर कस्टम उदाहरण प्रदान कर रहे हैं । से Microsoft.AspNet.WebApi.Client NuGet पैकेज एक है UriExtensions.ParseQueryString विधि का भी इस्तेमाल किया जा सकता है:

var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();

इसलिए यदि आप System.Web निर्भरता से बचना चाहते हैं और अपना रोल नहीं करना चाहते हैं, तो यह एक अच्छा विकल्प है।


3
वही फ़ंक्शन System.Net.Http नामस्थान में विस्तार के रूप में मौजूद है (नीचे मेरा उत्तर देखें), एक और संपूर्ण निर्भरता की कोई आवश्यकता नहीं ...
jvenema

@jvenema जहाँ से आप System.Net.ttp.ttp.Formatting निर्भरता जोड़ रहे हैं, मेरा मानना ​​है कि यह केवल Microsoft.AspNet.WebApi.Client NuGet पैकेज को जोड़कर प्रदान किया गया है।
जेम्स स्किमिंग

19

मैं System.Web पर निर्भरता को दूर करना चाहता था, ताकि "क्लाइंट-ओनली फ्रेमवर्क सबसेट" तक सीमित पूर्वापेक्षाएँ होने पर, मैं एक ClickOnce परिनियोजन के क्वेरी स्ट्रिंग को पार्स कर सकूं।

मुझे आरपी का जवाब पसंद आया। मैंने कुछ अतिरिक्त तर्क जोड़े।

public static NameValueCollection ParseQueryString(string s)
    {
        NameValueCollection nvc = new NameValueCollection();

        // remove anything other than query string from url
        if(s.Contains("?"))
        {
            s = s.Substring(s.IndexOf('?') + 1);
        }

        foreach (string vp in Regex.Split(s, "&"))
        {
            string[] singlePair = Regex.Split(vp, "=");
            if (singlePair.Length == 2)
            {
                nvc.Add(singlePair[0], singlePair[1]);
            }
            else
            {
                // only one key with no value specified in query string
                nvc.Add(singlePair[0], string.Empty);
            }
        }

        return nvc;
    }

यह वास्तव में विंडोज़ फोन के लिए मददगार है, आपको बस "NameValueCollection" को "SortedDictionnary <string, string>" से बदलना है
माइक ब्रायंट

4
एक शब्दकोश के लिए NameValueCollection स्विच करते समय सावधान रहें - वे समान नहीं हैं! क्वेरी स्ट्रिंग समान मान के साथ कई कुंजियों का समर्थन करती हैं, और इसलिए NameValueCollection।
मैट डेके

7

मुझे एक ऐसे फ़ंक्शन की आवश्यकता थी, जो ओएलएससी प्रश्नों के साथ काम करते समय पहले से उपलब्ध कराए गए से थोड़ा अधिक बहुमुखी हो।

  • मान में कई समान चिह्न हो सकते हैं
  • नाम और मूल्य दोनों में डिकोड किए गए वर्णों को डिकोड करें
  • क्लाइंट फ्रेमवर्क पर चलने में सक्षम
  • मोबाइल फ्रेमवर्क पर चलने में सक्षम।

यहाँ मेरा समाधान है:

Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
    Dim result = New System.Collections.Specialized.NameValueCollection(4)
    Dim query = uri.Query
    If Not String.IsNullOrEmpty(query) Then
        Dim pairs = query.Substring(1).Split("&"c)
        For Each pair In pairs
            Dim parts = pair.Split({"="c}, 2)

            Dim name = System.Uri.UnescapeDataString(parts(0))
            Dim value = If(parts.Length = 1, String.Empty,
                System.Uri.UnescapeDataString(parts(1)))

            result.Add(name, value)
        Next
    End If
    Return result
End Function

हो सकता है <Extension()>कि उरी में अपनी क्षमता को जोड़ने के लिए इससे निपटना भी बुरा न हो ।


7

इसे बिना System.Web, स्वयं लिखे बिना, और अतिरिक्त नुगेट पैकेज के बिना करने के लिए:

  1. एक संदर्भ जोड़ें System.Net.Http.Formatting
  2. जोड़ना using System.Net.Http;
  3. इस कोड का उपयोग करें:

    new Uri(uri).ParseQueryString()

https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx


3
आप कहां से System.Net.tt.Http.Formatting निर्भरता जोड़ रहे हैं, मेरा मानना ​​है कि यह केवल Microsoft.AspNet.WebApi.Client NuGet पैकेज को जोड़कर प्रदान किया गया है।
जेम्स स्किमिंग

हुंह, मेरा बुरा। मुझे लगता है कि यह MVC फ्रेमवर्क के साथ आया है जो ऑटो-इंस्टॉल है, इसलिए मुझे किसी भी add'l पैकेज (प्रोग्राम फाइलें (x86) \ Microsoft ASP.NET \ ASP.NET MVC 4 \ Assemblies \ System.Net को जोड़ने की आवश्यकता नहीं थी। Http.Formatting.dll)
jvenema

System.Net.Formatting विस्तार VS2019 पारंपरिक फ्रेमवर्क संदर्भों से एक अलग सूची या टैब है
Sql Surfer

3

आप System.Web पर निर्भरता है कि उपयोग करने के लिए आवश्यक है से बचना चाहते हैं HttpUtility.ParseQueryString , आप इस्तेमाल कर सकते हैं Uriविस्तार विधि ParseQueryStringमें पाया System.Net.Http

System.Net.Httpअपनी परियोजना में एक संदर्भ (यदि आप पहले से ही नहीं है) जोड़ना सुनिश्चित करें ।

ध्यान दें कि आपको प्रतिक्रिया निकाय को मान्य में बदलना है Uriताकि ParseQueryString(में System.Net.Http) काम करे।

string body = "value1=randomvalue1&value2=randomValue2";

// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();

System.Net.Formatting विस्तार VS2019 पारंपरिक संदर्भ संदर्भों से अलग विस्तार संदर्भ डालता है।
Sql सर्फर

2
    private void button1_Click( object sender, EventArgs e )
    {
        string s = @"p1=6&p2=7&p3=8";
        NameValueCollection nvc = new NameValueCollection();

        foreach ( string vp in Regex.Split( s, "&" ) )
        {
            string[] singlePair = Regex.Split( vp, "=" );
            if ( singlePair.Length == 2 )
            {
                nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );    
            }    
        }
    }

5
अर्धविराम को http में एक पैरामीटर विभाजक के रूप में भी अनुमति दी गई है, पहिया को सुदृढ़ करने के लिए बेहतर नहीं है
मैथ्यू लॉक


1

बस Request.QueryString का उपयोग करें। AllKeys को एक अन्य उत्तर के रूप में उल्लेख किया गया है जिसमें आपको कुंजियों की एक सरणी मिलती है।


1

HttpUtility.ParseQueryString(Request.Url.Query)वापसी HttpValueCollection(आंतरिक वर्ग) है। इससे विरासत में मिला है NameValueCollection

    var qs = HttpUtility.ParseQueryString(Request.Url.Query);
    qs.Remove("foo"); 

    string url = "~/Default.aspx"; 
    if (qs.Count > 0)
       url = url + "?" + qs.ToString();

    Response.Redirect(url); 

1

यदि आप System.Web निर्भरता नहीं चाहते हैं, तो बस इस स्रोत कोड को HttpUtility वर्ग से चिपकाएँ।

मैं सिर्फ मोनो के स्रोत कोड से इसे एक साथ मार दिया । इसमें HttpUtility और यह सब निर्भरताएं हैं (जैसे कि IHtmlString, Helpers, HttpEncoder, HttpQSCollection)।

फिर उपयोग करें HttpUtility.ParseQueryString

https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c


1

चूँकि हर कोई उसका समाधान चिपका रहा है। यहाँ मेरा खान :-) मुझे System.Webस्टोर किए गए हाइपरलिंक से आईडी मापदंडों को लाने के बिना एक वर्ग पुस्तकालय के भीतर से इसकी आवश्यकता थी ।

सोचा था कि मैं साझा करूंगा क्योंकि मुझे यह समाधान तेजी से और बेहतर लग रहा है।

public static class Statics
    public static Dictionary<string, string> QueryParse(string url)
    {
        Dictionary<string, string> qDict = new Dictionary<string, string>();
        foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
        {
            string[] qVal = qPair.Split('=');
            qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
        }
        return qDict;
    }

    public static string QueryGet(string url, string param)
    {
        var qDict = QueryParse(url);
        return qDict[param];
    }
}

उपयोग:

Statics.QueryGet(url, "id")

1
इस विधि के साथ बस एक समस्या: एक क्वेरी स्ट्रिंग में दिए गए पैरामीटर के लिए एक से अधिक मूल्य हो सकते हैं। इस स्थिति में, आपकी विधि एक डुप्लिकेट कुंजी त्रुटि को फेंक देगी।
थॉमस लेवेस्क

हां, कम से कम NameValueCollection का उपयोग करें, डुप्लिकेट कुंजियों के साथ querystrings पूरी तरह से कानूनी हैं।
चाड ग्रांट

इसके अलावा, आपका शब्दकोश संवेदनशील है, इसलिए X = 1 और x = 1 अलग-अलग कुंजी होंगे। नए शब्दकोश की आवश्यकता है <string, string> (StringComparer.OrdinalIgnoreCase);
चाड ग्रांट


0

सभी Querystring मान प्राप्त करने के लिए यह प्रयास करें:

    Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)

Dim sb As New StringBuilder("<br />")
For Each s As String In qscoll.AllKeys

  Response.Write(s & " - " & qscoll(s) & "<br />")

Next s


0
let search = window.location.search;

console.log(search);

let qString = search.substring(1);

while(qString.indexOf("+") !== -1)

   qString  = qString.replace("+", "");

let qArray = qString.split("&");

let values = [];

for(let i = 0; i < qArray.length; i++){
   let pos = qArray[i].search("=");
   let keyVal = qArray[i].substring(0, pos);
   let dataVal = qArray[i].substring(pos + 1);
   dataVal = decodeURIComponent(dataVal);
   values[keyVal] = dataVal;
}

-1

मैं VB में josh-brown के C # संस्करण में अनुवाद करता हूं

private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
{
    var result = new System.Collections.Specialized.NameValueCollection(4);
    var query = uri.Query;
    if (!String.IsNullOrEmpty(query))
    {
        var pairs = query.Substring(1).Split("&".ToCharArray());
        foreach (var pair in pairs)
        {
            var parts = pair.Split("=".ToCharArray(), 2);
            var name = System.Uri.UnescapeDataString(parts[0]);
            var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
            result.Add(name, value);
        }
    }
    return result;
}

-2

यह मेरा कोड है, मुझे लगता है कि यह बहुत उपयोगी है:

public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
{
    System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
    if (ItemToRemoveOrInsert != null)
    {
        filtered.Remove(ItemToRemoveOrInsert);
        if (!string.IsNullOrWhiteSpace(InsertValue))
        {
            filtered.Add(ItemToRemoveOrInsert, InsertValue);
        }
    }

    string StrQr = string.Join("&", filtered.AllKeys.Select(key => key + "=" + filtered[key]).ToArray());
    if (!string.IsNullOrWhiteSpace(StrQr)){
        StrQr="?" + StrQr;
    }

    return StrQr;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.