C # में URL के लिए क्वेरी स्ट्रिंग कैसे बनाएँ?


473

कोड से वेब संसाधनों को कॉल करते समय एक सामान्य कार्य सभी आवश्यक मापदंडों को शामिल करने के लिए एक क्वेरी स्ट्रिंग का निर्माण कर रहा है। हालांकि हर तरह से कोई रॉकेट साइंस नहीं है, ऐसे कुछ निफ्टी डिटेल्स हैं, जिनका आपको ध्यान रखना चाहिए, &अगर कोई पहला पैरामीटर नहीं है, तो पैरामीटर को एन्कोडिंग करना आदि।

यह करने के लिए कोड बहुत सरल है, लेकिन थोड़ा थकाऊ:

StringBuilder SB = new StringBuilder();
if (NeedsToAddParameter A) 
{ 
  SB.Append("A="); SB.Append(HttpUtility.UrlEncode("TheValueOfA")); 
}

if (NeedsToAddParameter B) 
{
  if (SB.Length>0) SB.Append("&"); 
  SB.Append("B="); SB.Append(HttpUtility.UrlEncode("TheValueOfB")); }
}

यह एक ऐसा सामान्य कार्य है जो एक उपयोगिता वर्ग की मौजूदगी की उम्मीद करेगा जो इसे और अधिक सुरुचिपूर्ण और पठनीय बनाता है। MSDN को स्कैन करना, मैं एक खोजने में विफल रहा- जो मुझे निम्नलिखित प्रश्न पर लाता है:

सबसे सुंदर स्वच्छ तरीका क्या है जो आप ऊपर करने के बारे में जानते हैं?


26
यह थोड़ा दुखद है कि वर्तमान समय में भी, querystrings से निपटने के लिए कोई सीधा रास्ता नहीं लगता है । और सीधे तौर पर, मेरा मतलब है एक ओओबी, गैर-आंतरिक, मानक-अनुरूप रूपरेखा वर्ग। या शायद मुझे कुछ याद आ रहा है?
२air

5
आप कुछ भी याद नहीं कर रहे हैं। क्वेरिस्ट्रिंग बिल्डिंग फ्रेमवर्क में एक प्रमुख अंतर है जिसे मैंने फ्लूरल से भरने की कोशिश की है ।
टोड मेनियर


तुम बस मुझे सोच रहे थे कि मुझे एक निर्माण करना चाहिए .. नया UrlBuilder (मौजूदा) ।AddQuery ("कुंजी", "मूल्य")। ToString ()
डेमेट्रिस लेप्टोस

जवाबों:


293

यदि आप हुड के नीचे देखते हैं तो QueryString प्रॉपर्टी एक NameValueCollection है। जब मैंने इसी तरह की चीजें की हैं तो मुझे आमतौर पर सीरियल करने में दिलचस्पी होती है और निराशा होती है इसलिए मेरा सुझाव है कि NameValueCollection का निर्माण करें और फिर पास करें:

using System.Linq;
using System.Web;
using System.Collections.Specialized;

private string ToQueryString(NameValueCollection nvc)
{
    var array = (
        from key in nvc.AllKeys
        from value in nvc.GetValues(key)
            select string.Format(
                "{0}={1}",
                HttpUtility.UrlEncode(key),
                HttpUtility.UrlEncode(value))
        ).ToArray();
    return "?" + string.Join("&", array);
}

मुझे लगता है कि LINQ में भी ऐसा करने का एक शानदार तरीका है ...


22
HTTP कल्पना (RFC 2616) इस बारे में कुछ भी नहीं कहती है कि क्वेरी में क्या तार हो सकते हैं। न ही RFC 3986, जो सामान्य URI प्रारूप को परिभाषित करता है। कुंजी / मूल्य जोड़ी प्रारूप जिसे आमतौर पर उपयोग किया जाता है application/x-www-form-urlencoded, उसे कहा जाता है , और वास्तव में HTML द्वारा परिभाषित किया जाता है , GETअनुरोध के रूप में फॉर्म डेटा जमा करने के उद्देश्य से । एचटीएमएल 5 इस प्रारूप में प्रति कुंजी कई मानों को मना नहीं करता है, और वास्तव में यह आवश्यक है कि ब्राउज़र उस मामले में प्रति कुंजी कई मान उत्पन्न करता है जिसमें पृष्ठ (गलत तरीके से) में एक ही nameविशेषता वाले कई फ़ील्ड शामिल हैं । Goo.gl/uk1Ag
डैनियल कैसिडी

14
@annakata: मुझे पता है कि मेरी टिप्पणी एक साल से अधिक पुरानी है (और दो साल से अधिक पुराने उत्तर पर!), लेकिन NameValueCollection बहुत महत्वपूर्ण है प्रति कुंजी कई मानों का समर्थन करता है, GetValues ​​(कुंजी) विधि का उपयोग करके।
मौरिसियो शेफ़र

4
@MauricioScheffer: लेकिन NameValueCollection एक querystring "सही ढंग से" में परिवर्तित नहीं होता है। उदाहरण के लिए, यदि आप WebClient पर QueryString पैरामीटर सेट करते हैं, जहां एक ही कुंजी कई बार मौजूद होती है, तो यह "पथ? कुंजी = मान 1" के बजाय "पथ? कुंजी = मान 2" में बदल जाती है, जो एक सामान्य (मानक) है? ;) पैटर्न।
डेविड पोप

8
प्रति कुंजी कई मानों के बारे में, मेरा मानना ​​है कि HTML में, यदि आपके पास एक बहु-चयन सूची-बॉक्स है जिसमें कई आइटम चयनित और प्रस्तुत किए गए हैं, तो उन्हें डेविड द्वारा उल्लिखित कई मूल्य प्रारूप में भेजा जाता है।
सैम

10
आप HttpUtility.UrlEncode के बजाय Uri.EscapeDataString का उपयोग करना चाह सकते हैं जो अधिक पोर्टेबल है। देखें stackoverflow.com/questions/2573290/...
PEK

687

आप HttpValueCollectionकॉल करके एक नया लेखन उदाहरण बना सकते हैं System.Web.HttpUtility.ParseQueryString(string.Empty), और फिर इसे किसी भी रूप में उपयोग कर सकते हैं NameValueCollection। एक बार जब आप अपने इच्छित मानों को जोड़ लेते हैं, तो आप ToStringइस प्रकार संग्रह स्ट्रिंग पर कॉल कर सकते हैं:

NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);

queryString.Add("key1", "value1");
queryString.Add("key2", "value2");

return queryString.ToString(); // Returns "key1=value1&key2=value2", all URL-encoded

HttpValueCollectionआंतरिक है और इसलिए आप सीधे एक उदाहरण का निर्माण नहीं कर सकते। हालाँकि, एक बार जब आप एक उदाहरण प्राप्त करते हैं तो आप इसे किसी अन्य की तरह उपयोग कर सकते हैं NameValueCollection। चूँकि आप जिस वास्तविक ऑब्जेक्ट के साथ काम कर रहे हैं वह एक है HttpValueCollection, कॉल करने के लिए ToString विधि उस ओवरराइड विधि को कॉल करेगी HttpValueCollection, जो URL-एन्कोडेड क्वेरी स्ट्रिंग के रूप में संग्रह को प्रारूपित करती है।

एक समान मुद्दे के जवाब के लिए एसओ और वेब पर खोज करने के बाद, यह सबसे सरल समाधान है जो मुझे मिल सकता है।

.NET कोर

यदि आप .NET कोर में काम कर रहे हैं, तो आप Microsoft.AspNetCore.WebUtilities.QueryHelpersक्लास का उपयोग कर सकते हैं , जो इसे बहुत सरल करता है।

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webutilities.queryhelpers

नमूना कोड:

const string url = "https://customer-information.azure-api.net/customers/search/taxnbr";
var param = new Dictionary<string, string>() { { "CIKey", "123456789" } };

var newUrl = new Uri(QueryHelpers.AddQueryString(url, param));

6
आप शायद एक विस्तार विधि बना सकते हैं जिसे IDUREDIA इंटरफ़ेस के लिए TOURLQueryString कहा जाता है:public static string ToURLQueryString(this IDictionary dict) { ... }
रॉय टिंकर

65
यह विधि मल्टीबाइट पात्रों के लिए मानक-अनुरूप नहीं है । यह उन्हें% XX% XX के बजाय% uXXXX के रूप में एन्कोड करेगा। परिणामी क्वेरी स्ट्रिंग को गलत तरीके से वेब सर्वर द्वारा व्याख्यायित किया जा सकता है। यह यहां तक ​​कि आंतरिक ढांचे के वर्ग HttpValueCollection में HttpUtility.ParseQueryString () द्वारा लौटाया गया है। टिप्पणी कहती है कि वे इस व्यवहार को पिछड़ेपन के अनुकूल कारणों के लिए रखते हैं।
एलेक्स

25
ध्यान दें कि HttpUtilityPraseQueryString ("") और नए NameValueCollection () के बीच एक महत्वपूर्ण अंतर है - केवल HttpUtility परिणाम ToString को ओवरराइड करेगा () एक उचित querystring का उत्पादन करने के लिए
फ्रैंक Schwieterman

7
उन मामलों के बारे में जहां आप क्वेरी स्ट्रिंग में नाम के कई उदाहरण चाहते हैं? उदाहरण के लिए, "टाइप = 10 और टाइप = 21"।
फिनिस्टर

7
@ फ़िनस्टर आप Addविधि का उपयोग करके क्वेरी स्ट्रिंग में एक नाम के कई उदाहरण जोड़ सकते हैं । Ie विधि का queryString.Add("type", "1"); queryString.Add("type", "2"); उपयोग करना Addवास्तव में इस समय के सभी को करने का एक बेहतर तरीका है।
jeremysawesome

94

रॉय टिंकर की टिप्पणी से प्रेरणा लेकर, मैंने उरी वर्ग पर एक सरल विस्तार पद्धति का उपयोग करके समाप्त किया, जो मेरे कोड को संक्षिप्त और स्वच्छ रखता है:

using System.Web;

public static class HttpExtensions
{
    public static Uri AddQuery(this Uri uri, string name, string value)
    {
        var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);

        httpValueCollection.Remove(name);
        httpValueCollection.Add(name, value);

        var ub = new UriBuilder(uri);
        ub.Query = httpValueCollection.ToString();

        return ub.Uri;
    }
}

उपयोग:

Uri url = new Uri("http://localhost/rest/something/browse").
          AddQuery("page", "0").
          AddQuery("pageSize", "200");

संपादित करें - मानक अनुरूप संस्करण

जैसा कि कई लोगों ने बताया, httpValueCollection.ToString()यूनिकोड वर्णों को एक गैर-मानक-अनुरूप तरीके से कूटबद्ध किया जाता है। यह उसी एक्सटेंशन विधि का एक प्रकार है, जो इस तरह के वर्णों HttpUtility.UrlEncodeको पदावनत HttpUtility.UrlEncodeUnicodeविधि के बजाय चालान विधि द्वारा संभालती है ।

using System.Web;

public static Uri AddQuery(this Uri uri, string name, string value)
{
    var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);

    httpValueCollection.Remove(name);
    httpValueCollection.Add(name, value);

    var ub = new UriBuilder(uri);

    // this code block is taken from httpValueCollection.ToString() method
    // and modified so it encodes strings with HttpUtility.UrlEncode
    if (httpValueCollection.Count == 0)
        ub.Query = String.Empty;
    else
    {
        var sb = new StringBuilder();

        for (int i = 0; i < httpValueCollection.Count; i++)
        {
            string text = httpValueCollection.GetKey(i);
            {
                text = HttpUtility.UrlEncode(text);

                string val = (text != null) ? (text + "=") : string.Empty;
                string[] vals = httpValueCollection.GetValues(i);

                if (sb.Length > 0)
                    sb.Append('&');

                if (vals == null || vals.Length == 0)
                    sb.Append(val);
                else
                {
                    if (vals.Length == 1)
                    {
                        sb.Append(val);
                        sb.Append(HttpUtility.UrlEncode(vals[0]));
                    }
                    else
                    {
                        for (int j = 0; j < vals.Length; j++)
                        {
                            if (j > 0)
                                sb.Append('&');

                            sb.Append(val);
                            sb.Append(HttpUtility.UrlEncode(vals[j]));
                        }
                    }
                }
            }
        }

        ub.Query = sb.ToString();
    }

    return ub.Uri;
}

3
उत्तम। मेरे घर के पुस्तकालय में जोड़ा गया। :)
एंडी

1
आपको मान को एनकोड करना चाहिए। queryString.Add (नाम, Uri.EscapeDataString (मान));
उफुक हकीओउल्लारि

2
इस उत्तर को बेहतर बनाने के लिए धन्यवाद। इसने मल्टीबाइट पात्रों के साथ समस्या को ठीक किया।
उफुक हकीओउल्लार

9
ध्यान दें, यह रिश्तेदार url के साथ काम नहीं करता है क्योंकि आप UriBuilder को किसी रिश्तेदार Uri से तुरंत नहीं कर सकते।
यूरी फकटोरोविच

1
मैंने एक हटाने की कुंजी जोड़ी ताकि एक डुप्लिकेट जोड़ा न जा सके। dotnetfiddle.net/hTlyAd
पॉल

29

मैंने कुछ समय पहले इसी तरह के सवाल का जवाब दिया था। मूल रूप से, क्लास का उपयोग करने का सबसे अच्छा तरीका होगा HttpValueCollection, जो ASP.NET की Request.QueryStringसंपत्ति वास्तव में है, दुर्भाग्य से यह .NET फ्रेमवर्क में आंतरिक है। आप इसे पकड़ने के लिए रिफ्लेक्टर का उपयोग कर सकते हैं (और इसे अपने यूटिल्स वर्ग में रखें)। इस तरह आप एक NameValueCollection की तरह क्वेरी स्ट्रिंग में हेरफेर कर सकते हैं, लेकिन सभी url एन्कोडिंग / डिकोडिंग मुद्दों के साथ आपके लिए देखभाल की गई।

HttpValueCollectionफैली हुई है NameValueCollection, और एक कंस्ट्रक्टर है जो एक एन्कोडेड क्वेरी स्ट्रिंग (एम्परसेंड्स और प्रश्न चिह्न शामिल) लेता है , और यह ToString()अंतर्निहित संग्रह से क्वेरी स्ट्रिंग के पुनर्निर्माण के लिए एक विधि को ओवरराइड करता है ।

उदाहरण:

  var coll = new HttpValueCollection();

  coll["userId"] = "50";
  coll["paramA"] = "A";
  coll["paramB"] = "B";      

  string query = coll.ToString(true); // true means use urlencode

  Console.WriteLine(query); // prints: userId=50&paramA=A&paramB=B

धन्यवाद ... मैंने देखा कि NameValueCollection यह रिटर्न एक ToString () है जो अलग तरह से कार्य करता है, लेकिन ऐसा क्यों नहीं कर सकता है।
calebt

httpValueCollection.ToString()वास्तव में कॉल करना httpValueCollection.ToString(true)इसलिए अन्वेषण को जोड़ना trueआवश्यक नहीं है।
dav_i

5
HttpValueCollection एक आंतरिक वर्ग है इसलिए आप इसे तत्काल नहीं दे सकते।
ओजबा

29

यहाँ एक विस्तार विधि के रूप में धाराप्रवाह / लम्बा-ईश रास्ता (पिछली पोस्ट में अवधारणाओं का संयोजन) है जो एक ही कुंजी के लिए कई मानों का समर्थन करता है। मेरी व्यक्तिगत पसंद इस तरह से सामान के लिए टीम के अन्य सदस्यों द्वारा खोज-क्षमता के लिए रैपर पर एक्सटेंशन है। ध्यान दें कि एन्कोडिंग विधियों के बारे में विवाद है, इसके बारे में ढेर सारे पोस्ट ढेर अतिप्रवाह (एक ऐसा पोस्ट ) और एमएसडीएन ब्लॉगर्स (जैसे यह एक )।

public static string ToQueryString(this NameValueCollection source)
{
    return String.Join("&", source.AllKeys
        .SelectMany(key => source.GetValues(key)
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))))
        .ToArray());
}

संपादित करें: अशक्त समर्थन के साथ, हालांकि आपको संभवतः इसे अपनी विशेष स्थिति के लिए अनुकूलित करने की आवश्यकता होगी

public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
    return source != null ? String.Join("&", source.AllKeys
        .Where(key => !removeEmptyEntries || source.GetValues(key)
            .Where(value => !String.IsNullOrEmpty(value))
            .Any())
        .SelectMany(key => source.GetValues(key)
            .Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
        .ToArray())
        : string.Empty;
}

1
यदि कोई मान शून्य है, तो यह विफल रहता है
जोश नू

यह गलत है यह प्रत्येक कुंजी मान जोड़ी के लिए कई क्वेरी स्ट्रिंग उत्पन्न करता है
गायन

@GayanRanasinghe: इसका क्या मतलब है?
मत्ती वीरकुंकेन

22

Flurl [प्रकटीकरण: मैं लेखक हूं] अनाम वस्तुओं के माध्यम से क्वेरी स्ट्रिंग बनाने का समर्थन करता है (अन्य तरीकों के साथ):

var url = "http://www.some-api.com".SetQueryParams(new
{
    api_key = ConfigurationManager.AppSettings["SomeApiKey"],
    max_results = 20,
    q = "Don't worry, I'll get encoded!"
});

वैकल्पिक Flurl.Http साथी की lib आपको HTTP कॉल को उसी धाराप्रवाह कॉल श्रृंखला से करने की अनुमति देती है, जो इसे पूर्ण विकसित REST क्लाइंट में विस्तारित करती है:

T result = await "https://api.mysite.com"
    .AppendPathSegment("person")
    .SetQueryParams(new { ap_key = "my-key" })
    .WithOAuthBearerToken("MyToken")
    .PostJsonAsync(new { first_name = firstName, last_name = lastName })
    .ReceiveJson<T>();

पूरा पैकेज NuGet पर उपलब्ध है:

PM> Install-Package Flurl.Http

या केवल स्टैंड-अलोन URL बिल्डर:

PM> Install-Package Flurl


20

यहां मेरी देर से एंट्री हुई। मुझे विभिन्न कारणों से कोई भी पसंद नहीं आया, इसलिए मैंने अपना लिखा।

यह संस्करण सुविधाएँ:

  • StringBuilder का उपयोग केवल। कोई ToArray () कॉल या अन्य एक्सटेंशन विधियां नहीं। यह अन्य प्रतिक्रियाओं के रूप में बहुत सुंदर नहीं लगता है, लेकिन मुझे लगता है कि यह एक मुख्य कार्य है इसलिए दक्षता "धाराप्रवाह", "वन-लाइनर" कोड होने से अधिक महत्वपूर्ण है जो अक्षमताओं को छिपाते हैं।

  • प्रति कुंजी कई मान संभालता है। (यह खुद की जरूरत नहीं है, लेकिन सिर्फ मौरिसियो को चुप कराने के लिए;)

    public string ToQueryString(NameValueCollection nvc)
    {
        StringBuilder sb = new StringBuilder("?");
    
        bool first = true;
    
        foreach (string key in nvc.AllKeys)
        {
            foreach (string value in nvc.GetValues(key))
            {
                if (!first)
                {
                    sb.Append("&");
                }
    
                sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
    
                first = false;
            }
        }
    
        return sb.ToString();
    }

उदाहरण उपयोग

        var queryParams = new NameValueCollection()
        {
            { "x", "1" },
            { "y", "2" },
            { "foo", "bar" },
            { "foo", "baz" },
            { "special chars", "? = &" },
        };

        string url = "http://example.com/stuff" + ToQueryString(queryParams);

        Console.WriteLine(url);

उत्पादन

http://example.com/stuff?x=1&y=2&foo=bar&foo=baz&special%20chars=%3F%20%3D%20%26

मुझे पसंद है कि यह HttpUtility का उपयोग नहीं करता है जो System.Web के अंतर्गत है और हर जगह उपलब्ध नहीं है।
कुगेल

लिनक का उपयोग नहीं करने और HttpUtility का उपयोग नहीं करने के लिए +1। मैं एक खाली एसबी बनाऊंगा और "बूल फर्स्ट" वेरिएबल को खोदूंगा और फिर लूप में sb.Append (sb.Length == 0? "?": "&") को sb.AppendFormat () से पहले ले जाऊंगा। अब अगर nvc खाली है तो विधि एक अकेले के बजाय एक खाली स्ट्रिंग लौटा देगी "?"।
मैथ्यू लेगर

यह उत्तर कई मानों के साथ एकल मापदंडों को संभालता है। जैसे? id = 1 & id = 3 & id = 2 & id = 9
Mathemats

12

विस्तार तरीकों को बनाने के बारे में जो आपको इस तरह से एक धाराप्रवाह शैली में पैरामीटर जोड़ने की अनुमति देते हैं?

string a = "http://www.somedomain.com/somepage.html"
    .AddQueryParam("A", "TheValueOfA")
    .AddQueryParam("B", "TheValueOfB")
    .AddQueryParam("Z", "TheValueOfZ");

string b = new StringBuilder("http://www.somedomain.com/anotherpage.html")
    .AddQueryParam("A", "TheValueOfA")
    .AddQueryParam("B", "TheValueOfB")
    .AddQueryParam("Z", "TheValueOfZ")
    .ToString(); 

यहाँ एक अधिभार है कि एक का उपयोग करता है string:

public static string AddQueryParam(
    this string source, string key, string value)
{
    string delim;
    if ((source == null) || !source.Contains("?"))
    {
        delim = "?";
    }
    else if (source.EndsWith("?") || source.EndsWith("&"))
    {
        delim = string.Empty;
    }
    else
    {
        delim = "&";
    }

    return source + delim + HttpUtility.UrlEncode(key)
        + "=" + HttpUtility.UrlEncode(value);
}

और यहाँ एक अधिभार है कि एक का उपयोग करता है StringBuilder:

public static StringBuilder AddQueryParam(
    this StringBuilder source, string key, string value)
{
    bool hasQuery = false;
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == '?')
        {
            hasQuery = true;
            break;
        }
    }

    string delim;
    if (!hasQuery)
    {
        delim = "?";
    }
    else if ((source[source.Length - 1] == '?')
        || (source[source.Length - 1] == '&'))
    {
        delim = string.Empty;
    }
    else
    {
        delim = "&";
    }

    return source.Append(delim).Append(HttpUtility.UrlEncode(key))
        .Append("=").Append(HttpUtility.UrlEncode(value));
}

: +1: सरल स्ट्रिंग-आधारित एक्सटेंशन विधि के लिए। अन्य उत्तर के कुछ और बढ़त मामलों को कवर कर सकते हैं, लेकिन यह मेरी स्थिति के लिए पर्याप्त है, और यह मुझे एक का निर्माण करने की आवश्यकता नहीं है NameValueCollection, HttpValueCollectionहै, या एक Uriपहले। धन्यवाद!
स्टेनली जी।

11

मुझे पोर्टेबल क्लास लाइब्रेरी (पीसीएल) के लिए उसी समस्या को हल करने की आवश्यकता है जो मैं काम कर रहा हूं। इस स्थिति में, मेरे पास System.Web तक पहुंच नहीं है, इसलिए मैं ParseQueryString का उपयोग नहीं कर सकता।

इसके बजाय मुझे System.Net.Http.FormUrlEncodedContentऐसा पसंद था:

var url = new UriBuilder("http://example.com");

url.Query = new FormUrlEncodedContent(new Dictionary<string,string>()
{
    {"param1", "val1"},
    {"param2", "val2"},
    {"param3", "val3"},
}).ReadAsStringAsync().Result;

यह वह तकनीक है जिसका मैं उपयोग करता हूं, और इसे एक अन्य प्रश्न में संदर्भित किया है http://stackoverflow.com/a/26744471/2108310 फर्क सिर्फ इतना है कि मैं KeyValue जोड़े की एक सरणी का उपयोग करता हूं ... सिस्टम के संदर्भ की आवश्यकता के अलावा। नेट (जो आपके बताये अनुसार पीसीएल उपलब्ध है) यह IMHO है जो इसे बिना किसी थर्ड पार्टी पैकेज के शामिल करने का सबसे सरल तरीका है, या कुछ होमब्रे स्पेगेटी मेस में एक साथ हॉब करने की कोशिश कर रहा है।
रोस्तोव

9
    public static string ToQueryString(this Dictionary<string, string> source)
    {
        return String.Join("&", source.Select(kvp => String.Format("{0}={1}", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))).ToArray());
    }

    public static string ToQueryString(this NameValueCollection source)
    {
        return String.Join("&", source.Cast<string>().Select(key => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(source[key]))).ToArray());
    }

1
अच्छा! लेकिन आपको .ToArray()एस की जरूरत नहीं है ।
एमपीएन

7

इस वर्ग को अपनी परियोजना में जोड़ें

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public class QueryStringBuilder
{
    private readonly List<KeyValuePair<string, object>> _list;

    public QueryStringBuilder()
    {
        _list = new List<KeyValuePair<string, object>>();
    }

    public void Add(string name, object value)
    {
        _list.Add(new KeyValuePair<string, object>(name, value));
    }

    public override string ToString()
    {
        return String.Join("&", _list.Select(kvp => String.Concat(Uri.EscapeDataString(kvp.Key), "=", Uri.EscapeDataString(kvp.Value.ToString()))));
    }
}

और इसे इस तरह से उपयोग करें:

var actual = new QueryStringBuilder {
    {"foo", 123},
    {"bar", "val31"},
    {"bar", "val32"}
};

actual.Add("a+b", "c+d");

actual.ToString(); // "foo=123&bar=val31&bar=val32&a%2bb=c%2bd"

अब, यह स्वीकृत उत्तर होना चाहिए; "फू [] = 1, फू [] = 2" जैसे सरणियों के लिए पूरी तरह से काम करता है और साथ ही साथ मापदंडों के क्रम को बनाए रखता है जो वैसे भी बहुत महत्वपूर्ण है।
सोरूस फलाहती

6

मेरी भेंट:

public static Uri AddQuery(this Uri uri, string name, string value)
{
    // this actually returns HttpValueCollection : NameValueCollection
    // which uses unicode compliant encoding on ToString()
    var query = HttpUtility.ParseQueryString(uri.Query);

    query.Add(name, value);

    var uriBuilder = new UriBuilder(uri)
    {
        Query = query.ToString()
    };

    return uriBuilder.Uri;
}

उपयोग:

var uri = new Uri("http://stackoverflow.com").AddQuery("such", "method")
                                             .AddQuery("wow", "soFluent");

// http://stackoverflow.com?such=method&wow=soFluent

मैं अपने दृष्टिकोण सरल और सुरुचिपूर्ण पसंद करते हैं, हालांकि, HttpUtility System.Web की आवश्यकता है
Ody

5

अनटाइटेड, लेकिन मुझे लगता है कि इन लाइनों के साथ कुछ अच्छी तरह से काम करेगा

public class QueryString
{
    private Dictionary<string,string> _Params = new Dictionary<string,string>();

    public overide ToString()
    {
        List<string> returnParams = new List<string>();

        foreach (KeyValuePair param in _Params)
        {
            returnParams.Add(String.Format("{0}={1}", param.Key, param.Value));
        }

        // return String.Format("?{0}", String.Join("&", returnParams.ToArray())); 

        // credit annakata
        return "?" + String.Join("&", returnParams.ToArray());
    }

    public void Add(string key, string value)
    {
        _Params.Add(key, HttpUtility.UrlEncode(value));
    }
}

QueryString query = new QueryString();

query.Add("param1", "value1");
query.Add("param2", "value2");

return query.ToString();

अच्छी तरह से समझाया लेकिन "पर प्रारूप! {0}" अनावश्यक रूप से महंगा है :)
annakata

वर्ग नाम बदलकर QueryString .. क्वेरी थोड़ा अस्पष्ट है
निक एलन

4

एक त्वरित विस्तार विधि आधारित संस्करण:

class Program
{
    static void Main(string[] args)
    {
        var parameters = new List<KeyValuePair<string, string>>
                             {
                                 new KeyValuePair<string, string>("A", "AValue"),
                                 new KeyValuePair<string, string>("B", "BValue")
                             };

        string output = "?" + string.Join("&", parameters.ConvertAll(param => param.ToQueryString()).ToArray());
    }
}

public static class KeyValueExtensions
{
    public static string ToQueryString(this KeyValuePair<string, string> obj)
    {
        return obj.Key + "=" + HttpUtility.UrlEncode(obj.Value);
    }
}

आप एक क्लॉज का उपयोग कर सकते हैं जो यह चुनने के लिए कि किन मानकों को स्ट्रिंग में जोड़ा जाता है।


3

यह मानते हुए कि आप अन्य विधानसभाओं पर निर्भरता कम करना चाहते हैं और चीजों को सरल रखना चाहते हैं, आप यह कर सकते हैं:

var sb = new System.Text.StringBuilder();

sb.Append("a=" + HttpUtility.UrlEncode("TheValueOfA") + "&");
sb.Append("b=" + HttpUtility.UrlEncode("TheValueOfB") + "&");
sb.Append("c=" + HttpUtility.UrlEncode("TheValueOfC") + "&");
sb.Append("d=" + HttpUtility.UrlEncode("TheValueOfD") + "&");

sb.Remove(sb.Length-1, 1); // Remove the final '&'

string result = sb.ToString();

यह छोरों के साथ भी अच्छा काम करता है। अंतिम एम्परसेंड हटाने को लूप के बाहर जाने की आवश्यकता होती है।

ध्यान दें कि पठनीयता ऑपरेटर का उपयोग पठनीयता में सुधार के लिए किया जाता है। स्ट्रिंगब्यूलर का उपयोग करने की लागत की तुलना में इसका उपयोग करने की लागत न्यूनतम है (मुझे लगता है कि जेफ एटवुड ने इस विषय पर कुछ पोस्ट किया है)।


3

अनाम ऑब्जेक्ट संस्करण बनाने के लिए शीर्ष उत्तर संयुक्त :

var queryString = HttpUtility2.BuildQueryString(new
{
    key2 = "value2",
    key1 = "value1",
});

इससे यह उत्पन्न होता है:

कुंजी 2 = मान 2 और कुंजी 1 = मान 1

यहाँ कोड है:

public static class HttpUtility2
{
    public static string BuildQueryString<T>(T obj)
    {
        var queryString = HttpUtility.ParseQueryString(string.Empty);

        foreach (var property in TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>())
        {
            var value = (property.GetValue(obj) ?? "").ToString();
            queryString.Add(property.Name, value);
        }

        return queryString.ToString();
    }
}

2

स्वीकृत समाधान के रूप में भी, लेकिन "डॉट" LINQ सिंटैक्स में ट्रांसफ़र किया ...

private string ToQueryString(NameValueCollection nvc)
{
    if (nvc == null) return String.Empty;
    var queryParams = 
          string.Join("&", nvc.AllKeys.Select(key => 
              string.Join("&", nvc.GetValues(key).Select(v => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(v))))));
    return "?" + queryParams;
}

2

मेरे पास उरी के लिए एक विस्तार विधि है:

  • अनाम वस्तुओं को स्वीकार करता है: uri.WithQuery(new { name = "value" })
  • string/stringजोड़े के संग्रह को स्वीकार करता है (जैसे Dictionary`2 )।
  • string/objectजोड़े के संग्रह को स्वीकार करता है (जैसे कि रूटवैल्यूडर )।
  • NameValueCollection स्वीकार करता है s ।
  • कुंजी द्वारा क्वेरी मानों को सॉर्ट करता है ताकि समान मान समान URI का उत्पादन करें।
  • प्रति कुंजी कई मानों का समर्थन करता है, उनके मूल क्रम को संरक्षित करता है।

प्रलेखित संस्करण यहां पाया जा सकता है

विस्तार:

public static Uri WithQuery(this Uri uri, object values)
{
    if (uri == null)
        throw new ArgumentNullException(nameof(uri));

    if (values != null)
    {
        var query = string.Join(
            "&", from p in ParseQueryValues(values)
                 where !string.IsNullOrWhiteSpace(p.Key)
                 let k = HttpUtility.UrlEncode(p.Key.Trim())
                 let v = HttpUtility.UrlEncode(p.Value)
                 orderby k
                 select string.IsNullOrEmpty(v) ? k : $"{k}={v}");

        if (query.Length != 0 || uri.Query.Length != 0)
            uri = new UriBuilder(uri) { Query = query }.Uri;
    }

    return uri;
}

क्वेरी पार्सर:

private static IEnumerable<KeyValuePair<string, string>> ParseQueryValues(object values)
{
    // Check if a name/value collection.
    var nvc = values as NameValueCollection;
    if (nvc != null)
        return from key in nvc.AllKeys
               from val in nvc.GetValues(key)
               select new KeyValuePair<string, string>(key, val);

    // Check if a string/string dictionary.
    var ssd = values as IEnumerable<KeyValuePair<string, string>>;
    if (ssd != null)
        return ssd;

    // Check if a string/object dictionary.
    var sod = values as IEnumerable<KeyValuePair<string, object>>;
    if (sod == null)
    {
        // Check if a non-generic dictionary.
        var ngd = values as IDictionary;
        if (ngd != null)
            sod = ngd.Cast<dynamic>().ToDictionary<dynamic, string, object>(
                p => p.Key.ToString(), p => p.Value as object);

        // Convert object properties to dictionary.
        if (sod == null)
            sod = new RouteValueDictionary(values);
    }

    // Normalize and return the values.
    return from pair in sod
           from val in pair.Value as IEnumerable<string>
            ?? new[] { pair.Value?.ToString() }
           select new KeyValuePair<string, string>(pair.Key, val);
}

यहाँ परीक्षण हैं:

var uri = new Uri("https://stackoverflow.com/yo?oldKey=oldValue");

// Test with a string/string dictionary.
var q = uri.WithQuery(new Dictionary<string, string>
{
    ["k1"] = string.Empty,
    ["k2"] = null,
    ["k3"] = "v3"
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1&k2&k3=v3"));

// Test with a string/object dictionary.
q = uri.WithQuery(new Dictionary<string, object>
{
    ["k1"] = "v1",
    ["k2"] = new[] { "v2a", "v2b" },
    ["k3"] = null
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3"));

// Test with a name/value collection.
var nvc = new NameValueCollection()
{
    ["k1"] = string.Empty,
    ["k2"] = "v2a"
};

nvc.Add("k2", "v2b");

q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1&k2=v2a&k2=v2b"));

// Test with any dictionary.
q = uri.WithQuery(new Dictionary<int, HashSet<string>>
{
    [1] = new HashSet<string> { "v1" },
    [2] = new HashSet<string> { "v2a", "v2b" },
    [3] = null
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?1=v1&2=v2a&2=v2b&3"));

// Test with an anonymous object.
q = uri.WithQuery(new
{
    k1 = "v1",
    k2 = new[] { "v2a", "v2b" },
    k3 = new List<string> { "v3" },
    k4 = true,
    k5 = null as Queue<string>
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3=v3&k4=True&k5"));

// Keep existing query using a name/value collection.
nvc = HttpUtility.ParseQueryString(uri.Query);
nvc.Add("newKey", "newValue");

q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?newKey=newValue&oldKey=oldValue"));

// Merge two query objects using the RouteValueDictionary.
var an1 = new { k1 = "v1" };
var an2 = new { k2 = "v2" };

q = uri.WithQuery(
    new RouteValueDictionary(an1).Concat(
        new RouteValueDictionary(an2)));

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2"));

2

HttpValueCollection के लिए चेन-सक्षम आवरण वर्ग:

namespace System.Web.Mvc {
    public class QueryStringBuilder {
        private NameValueCollection collection;
        public QueryStringBuilder() {
            collection = System.Web.HttpUtility.ParseQueryString(string.Empty);
        }
        public QueryStringBuilder Add(string key, string value) {
            collection.Add(key, value);
            return this;
        }
        public QueryStringBuilder Remove(string key) {
            collection.Remove(key);
            return this;
        }
        public string this[string key] {
            get { return collection[key]; }
            set { collection[key] = value; }
        }
        public string ToString() {
            return collection.ToString();
        }
    }
}

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

QueryStringBuilder parameters = new QueryStringBuilder()
    .Add("view", ViewBag.PageView)
    .Add("page", ViewBag.PageNumber)
    .Add("size", ViewBag.PageSize);
string queryString = parameters.ToString();

1

मैंने अपने पेजबेस क्लास में निम्न विधि जोड़ी।

protected void Redirect(string url)
    {
        Response.Redirect(url);
    }
protected void Redirect(string url, NameValueCollection querystrings)
    {
        StringBuilder redirectUrl = new StringBuilder(url);

        if (querystrings != null)
        {
            for (int index = 0; index < querystrings.Count; index++)
            {
                if (index == 0)
                {
                    redirectUrl.Append("?");
                }

                redirectUrl.Append(querystrings.Keys[index]);
                redirectUrl.Append("=");
                redirectUrl.Append(HttpUtility.UrlEncode(querystrings[index]));

                if (index < querystrings.Count - 1)
                {
                    redirectUrl.Append("&");
                }
            }
        }

        this.Redirect(redirectUrl.ToString());
    }

बुलाना:

NameValueCollection querystrings = new NameValueCollection();    
querystrings.Add("language", "en");
querystrings.Add("id", "134");
this.Redirect("http://www.mypage.com", querystrings);

1

मैंने कुछ विस्तार विधियाँ लिखीं जो मुझे QueryStrings के साथ काम करते समय बहुत उपयोगी लगीं। अक्सर मैं वर्तमान QueryString के साथ शुरू करना चाहता हूं और इसका उपयोग करने से पहले संशोधित करना चाहता हूं। कुछ इस तरह,

var res = Request.QueryString.Duplicate()
  .ChangeField("field1", "somevalue")
  .ChangeField("field2", "only if following is true", true)
  .ChangeField("id", id, id>0)
  .WriteLocalPathWithQuery(Request.Url)); //Uses context to write the path

अधिक और स्रोत के लिए: http://www.charlesrcook.com/archive/2008/07/23/c-extension-methods-for-asp.net-query-string-operations.aspx

यह बुनियादी है, लेकिन मुझे शैली पसंद है।


1

बस मेरे 2 सेंट में फेंकना चाहता था:

public static class HttpClientExt
{
    public static Uri AddQueryParams(this Uri uri, string query)
    {
        var ub = new UriBuilder(uri);
        ub.Query = string.IsNullOrEmpty(uri.Query) ? query : string.Join("&", uri.Query.Substring(1), query);
        return ub.Uri;
    }

    public static Uri AddQueryParams(this Uri uri, IEnumerable<string> query)
    {
        return uri.AddQueryParams(string.Join("&", query));
    } 

    public static Uri AddQueryParams(this Uri uri, string key, string value)
    {
        return uri.AddQueryParams(string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value)));
    }

    public static Uri AddQueryParams(this Uri uri, params KeyValuePair<string,string>[] kvps)
    {
        return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
    }

    public static Uri AddQueryParams(this Uri uri, IDictionary<string, string> kvps)
    {
        return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
    }

    public static Uri AddQueryParams(this Uri uri, NameValueCollection nvc)
    {
        return uri.AddQueryParams(nvc.AllKeys.SelectMany(nvc.GetValues, (key, value) => string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))));
    }
}

डॉक्स का कहना है किuri.Query एक के साथ शुरू होगा? अगर यह गैर-रिक्त है तो आप इसके और यदि आप इसे संशोधित करने जा रहे हैं तो आपको इसे ट्रिम कर देना चाहिए।

ध्यान दें कि HttpUtility.UrlEncodeमें पाया जाता है System.Web

उपयोग:

var uri = new Uri("https://api.del.icio.us/v1/posts/suggest").AddQueryParam("url","http://stackoverflow.com")

1

सुरुचिपूर्ण नहीं होने पर, मैंने एक सरल संस्करण का विकल्प चुना जो उपयोग नहीं करता है NameValueCollecitons- बस एक बिल्डर पैटर्न के चारों ओर लिपटा हुआ StringBuilder

public class UrlBuilder
{
    #region Variables / Properties

    private readonly StringBuilder _builder;

    #endregion Variables / Properties

    #region Constructor

    public UrlBuilder(string urlBase)
    {
        _builder = new StringBuilder(urlBase);
    }

    #endregion Constructor

    #region Methods

    public UrlBuilder AppendParameter(string paramName, string value)
    {
        if (_builder.ToString().Contains("?"))
            _builder.Append("&");
        else
            _builder.Append("?");

        _builder.Append(HttpUtility.UrlEncode(paramName));
        _builder.Append("=");
        _builder.Append(HttpUtility.UrlEncode(value));

        return this;
    }

    public override string ToString()
    {
        return _builder.ToString();
    }

    #endregion Methods
}

मौजूदा उत्तरों के अनुसार, मैंने HttpUtility.UrlEncodeकॉल का उपयोग करना सुनिश्चित किया । यह इस तरह प्रयोग किया जाता है:

string url = new UrlBuilder("http://www.somedomain.com/")
             .AppendParameter("a", "true")
             .AppendParameter("b", "muffin")
             .AppendParameter("c", "muffin button")
             .ToString();
// Result: http://www.somedomain.com?a=true&b=muffin&c=muffin%20button

1
// USAGE
[TestMethod]
public void TestUrlBuilder()
{
    Console.WriteLine(
        new UrlBuilder("http://www.google.com?A=B")
            .AddPath("SomePathName")
            .AddPath("AnotherPathName")
            .SetQuery("SomeQueryKey", "SomeQueryValue")
            .AlterQuery("A", x => x + "C"));
}

आउटपुट:

http://www.google.com/SomePathName/AnotherPathName?A=BC&SomeQueryKey=SomeQueryValue

कोड; आप सभी मुझे कहीं न कहीं धन्यवाद दे सकते हैं: डी

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

// By Demetris Leptos
namespace TheOperator.Foundation.Web
{
    public class UrlBuilder
    {
        public string Scheme { get; set; }

        public string Host { get; set; }

        public int? Port { get; set; }

        public List<string> Paths { get; set; }

        public SortedDictionary<string, string> QueryPairs { get; set; }

        public UrlBuilder(string url)
        {
            this.Paths = new List<string>();
            this.QueryPairs = new SortedDictionary<string, string>();

            string path = null;
            string query = null;
            Uri relativeUri = null;
            if (!Uri.TryCreate(url, UriKind.Relative, out relativeUri))
            {
                var uriBuilder = new UriBuilder(url);
                this.Scheme = uriBuilder.Scheme;
                this.Host = uriBuilder.Host;
                this.Port = uriBuilder.Port;
                path = uriBuilder.Path;
                query = uriBuilder.Query;
            }
            else
            {
                var queryIndex = url.IndexOf('?');
                if (queryIndex >= 0)
                {
                    path = url.Substring(0, queryIndex);
                    query = url.Substring(queryIndex + 1);
                }
                else
                {
                    path = url;
                }
            }
            this.Paths.AddRange(path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
            if (query != null)
            {
                var queryKeyValuePairs = HttpUtility.ParseQueryString(query);
                foreach (var queryKey in queryKeyValuePairs.AllKeys)
                {
                    this.QueryPairs[queryKey] = queryKeyValuePairs[queryKey];
                }
            }
        }

        public UrlBuilder AddPath(string value)
        {
            this.Paths.Add(value);
            return this;
        }

        public UrlBuilder SetQuery(string key, string value)
        {
            this.QueryPairs[key] = value;
            return this;
        }

        public UrlBuilder RemoveQuery(string key)
        {
            this.QueryPairs.Remove(key);
            return this;
        }

        public UrlBuilder AlterQuery(string key, Func<string, string> alterMethod, bool removeOnNull = false)
        {
            string value;
            this.QueryPairs.TryGetValue(key, out value);
            value = alterMethod(value);
            if (removeOnNull && value == null)
            {
                return this.RemoveQuery(key);
            }
            else
            {
                return this.SetQuery(key, value);
            }
        }

        public override string ToString()
        {
            var path = !string.IsNullOrWhiteSpace(this.Host)
                ? string.Join("/", this.Host, string.Join("/", this.Paths))
                : string.Join("/", this.Paths);
            var query = string.Join("&", this.QueryPairs.Select(x => string.Concat(x.Key, "=", HttpUtility.UrlEncode(x.Value))));
            return string.Concat(
                !string.IsNullOrWhiteSpace(this.Scheme) ? string.Concat(this.Scheme, "://") : null,
                path,
                !string.IsNullOrWhiteSpace(query) ? string.Concat("?", query) : null);
        }
    }
}

1

मैं डीएसओ द्वारा प्रस्तावित समाधान के साथ गया था (7:29 पर अगस्त 2 '11 को उत्तर दिया गया था), उनके समाधान को हेटप्लसिटी का उपयोग करने की आवश्यकता नहीं है। हालाँकि, Dotnetpearls में पोस्ट किए गए एक लेख के अनुसार , NameValueCollection का उपयोग करने की तुलना में एक डिक्शनरी का उपयोग तेज (प्रदर्शन में) है। यहाँ NameValueCollection के स्थान पर Dictionary का उपयोग करने के लिए DSO के समाधान को संशोधित किया गया है।

    public static Dictionary<string, string> QueryParametersDictionary()
    {
        var dictionary = new Dictionary<string, string>();
        dictionary.Add("name", "John Doe");
        dictionary.Add("address.city", "Seattle");
        dictionary.Add("address.state_code", "WA");
        dictionary.Add("api_key", "5352345263456345635");

        return dictionary;
    }

    public static string ToQueryString(Dictionary<string, string> nvc)
    {
        StringBuilder sb = new StringBuilder();

        bool first = true;

        foreach (KeyValuePair<string, string> pair in nvc)
        {
                if (!first)
                {
                    sb.Append("&");
                }

                sb.AppendFormat("{0}={1}", Uri.EscapeDataString(pair.Key), Uri.EscapeDataString(pair.Value));

                first = false;
        }

        return sb.ToString();
    }

1

क्वेरी स्ट्रिंग को URL से URL में जोड़ा जा सकता है:

  1. एक नाम मान संग्रह वस्तु बनाएं
  2. इस ऑब्जेक्ट में क्वेरी स्ट्रिंग आइटम और उनके मान जोड़ें
  3. इस नाम मान संग्रह ऑब्जेक्ट को url में एन्कोड करें कोड नीचे दिए गए लिंक में प्रदान किया गया है

https://blog.codingnovice.com/blog

public ActionResult Create()
{
    //declaring name value collection object
    NameValueCollection collection = new NameValueCollection();

    //adding new value to the name value collection object
    collection.Add("Id1", "wwe323");
    collection.Add("Id2", "454w");
    collection.Add("Id3", "tyt5656");
    collection.Add("Id4", "343wdsd");

    //generating query string
    string url = GenerateQueryString(collection);

    return View();
}

private string GenerateQueryString(NameValueCollection collection)
{
    var querystring = (
        from key in collection.AllKeys
        from value in collection.GetValues(key)
        select string.Format("{0}={1}",
            HttpUtility.UrlEncode(key),
            HttpUtility.UrlEncode(value))
    ).ToArray();
    return "?" + string.Join("&", querystring);
}

0

मैंने अपने रेजर प्रोजेक्ट के लिए अन्य उत्तरों के कुछ संकेतों का उपयोग करते हुए एक सहायक लिखा।

ParseQueryString व्यवसाय आवश्यक है क्योंकि हमें वर्तमान अनुरोध के QueryString ऑब्जेक्ट के साथ छेड़छाड़ करने की अनुमति नहीं है।

@helper GetQueryStringWithValue(string key, string value) {
    var queryString = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString());
    queryString[key] = value;
    @Html.Raw(queryString.ToString())
}

मैं इसे इस तरह से उपयोग करता हूं:

location.search = '?@Helpers.GetQueryStringWithValue("var-name", "var-value")';

यदि आप चाहते हैं कि यह एक से अधिक मूल्य ले, तो केवल एक डिक्शनरी में पैरामीटर बदलें और जोड़ियों को क्वेरी स्ट्रिंग में जोड़ें।


0

नीचे दिए गए कोड को ILSpy के माध्यम से HttpValueCollectionलागू किया ToStringजाता है, जो आपको एक नाम = मूल्य क्वेरिस्ट्रिंग देता है।

दुर्भाग्य से HttpValueCollection एक आंतरिक वर्ग है जिसका उपयोग करने पर आप केवल कभी वापस आते हैं HttpUtility.ParseQueryString()। मैंने इसके सभी दृश्य भागों को हटा दिया, और यह डिफ़ॉल्ट रूप से एन्कोड करता है:

public static class HttpExtensions
{
    public static string ToQueryString(this NameValueCollection collection)
    {
        // This is based off the NameValueCollection.ToString() implementation
        int count = collection.Count;
        if (count == 0)
            return string.Empty;

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < count; i++)
        {
            string text = collection.GetKey(i);
            text = HttpUtility.UrlEncodeUnicode(text);
            string value = (text != null) ? (text + "=") : string.Empty;
            string[] values = collection.GetValues(i);
            if (stringBuilder.Length > 0)
            {
                stringBuilder.Append('&');
            }
            if (values == null || values.Length == 0)
            {
                stringBuilder.Append(value);
            }
            else
            {
                if (values.Length == 1)
                {
                    stringBuilder.Append(value);
                    string text2 = values[0];
                    text2 = HttpUtility.UrlEncodeUnicode(text2);
                    stringBuilder.Append(text2);
                }
                else
                {
                    for (int j = 0; j < values.Length; j++)
                    {
                        if (j > 0)
                        {
                            stringBuilder.Append('&');
                        }
                        stringBuilder.Append(value);
                        string text2 = values[j];
                        text2 = HttpUtility.UrlEncodeUnicode(text2);
                        stringBuilder.Append(text2);
                    }
                }
            }
        }

        return stringBuilder.ToString();
    }
}

0

यह थोड़े अधिक कॉम्पैक्ट को छोड़कर स्वीकृत उत्तर के समान है:

private string ToQueryString(NameValueCollection nvc)
{
    return "?" + string.Join("&", nvc.AllKeys.Select(k => string.Format("{0}={1}", 
        HttpUtility.UrlEncode(k), 
        HttpUtility.UrlEncode(nvc[k]))));
}

0

बस उन लोगों के लिए जिन्हें शीर्ष-उत्तर के VB.NET संस्करण की आवश्यकता है:

Public Function ToQueryString(nvc As System.Collections.Specialized.NameValueCollection) As String
    Dim array As String() = nvc.AllKeys.SelectMany(Function(key As String) nvc.GetValues(key), Function(key As String, value As String) String.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(key), System.Web.HttpUtility.UrlEncode(value))).ToArray()
    Return "?" + String.Join("&", array)
End Function

और LINQ बिना संस्करण:

Public Function ToQueryString(nvc As System.Collections.Specialized.NameValueCollection) As String
    Dim lsParams As New List(Of String)()

    For Each strKey As String In nvc.AllKeys
        Dim astrValue As String() = nvc.GetValues(strKey)

        For Each strValue As String In astrValue
            lsParams.Add(String.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(strKey), System.Web.HttpUtility.UrlEncode(strValue)))
        Next ' Next strValue
    Next ' strKey
    Dim astrParams As String() = lsParams.ToArray()
    lsParams.Clear()
    lsParams = Nothing

    Return "?" + String.Join("&", astrParams)
End Function ' ToQueryString

और LINQ के बिना C # संस्करण:

    public static string ToQueryString(System.Collections.Specialized.NameValueCollection nvc)
    {
        List<string> lsParams = new List<string>();

        foreach (string strKey in nvc.AllKeys)
        {
            string[] astrValue = nvc.GetValues(strKey);

            foreach (string strValue in astrValue)
            {
                lsParams.Add(string.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(strKey), System.Web.HttpUtility.UrlEncode(strValue)));
            } // Next strValue

        } // Next strKey

        string[] astrParams =lsParams.ToArray();
        lsParams.Clear();
        lsParams = null;

        return "?" + string.Join("&", astrParams);
    } // End Function ToQueryString
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.