NameValueCollection में फ़ॉरवर्ड KeyValuePair?


79

मेरे पास यह कोड है:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);        
foreach (KeyValuePair<String,String> pr in nv) {
    //process KeyValuePair          
}

यह संकलित करता है, लेकिन जब मैं इसे चलाने की कोशिश करता हूं तो मुझे ए मिलता है InvalidCastException ।

ऐसा क्यों है? मैं KeyValuePairएक से अधिक का उपयोग क्यों नहीं कर सकता NameValueCollection, और मुझे इसके बजाय क्या उपयोग करना चाहिए?


मुझे यह पसंद है कि मैं एक शब्दकोश के लिए एक शब्दकोश के अलावा एक बैकिंग शब्दकोश चर बनाने के बिना एक init कर सकते हैं। var nv = HttpUtility.ParseQueryString(Request.Url.Query); var qsDic = nv.Cast<object>().ToDictionary<object, string, object>(key => (string) key, key => nv[(string) key]);
— मफिन मैन

जवाबों:


133

सबसे पहले, NameValueCollectionउपयोग नहीं करता है KeyValuePair<String,String>। इसके अलावा, foreachकेवल कुंजी को उजागर करता है:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);        
foreach (string key in nv) {
    var value = nv[key];

}

3
हम्म, यह अजीब तरह का है। मुझे उम्मीद होगी कि दोनों को एक साथ पाने का एक तरीका होगा।
— ओलिवर

27
हम सभी तब करते हैं जब हम NVC का उपयोग करना शुरू करते हैं।
— jgauffin

1
सोच रहा था कि यह कैसे किया जाए ... धन्यवाद! Btw, आपको निर्दिष्ट करने की आवश्यकता नहीं है KeyValuePair<String,String>क्योंकि NameValueCollection केवल स्ट्रिंग, स्ट्रिंग का उपयोग करता है। इसे निर्दिष्ट करने की आवश्यकता नहीं है।
— द गेटकीपर

7
डुप्लिकेट कुंजियों के लिए यह कोड कैसे काम करता है, इसके बारे में जानकारी रखें। जब डुप्लिकेट कुंजियाँ मौजूद होती हैं, तो यह "कुंजी मान 1" के बजाय "कुंजी मान 2" और फिर "कुंजी मान 3" के बजाय "कुंजी मान 1, मान 2, मान 3" लौटाएगा।
— डग एस

3
@ नाम: NameValueCollection .NET में पहले संग्रह प्रकारों में से एक है। यह असंवेदनशील है और मौजूदा मूल्यों (जो कुछ प्रोटोकॉल के लिए उपयोगी है) को मर्ज कर देता है
— jgauffin

12

आप सीधे ऐसा नहीं कर सकते हैं, लेकिन आप एक एक्सटेंशन विधि बना सकते हैं:

public static IEnumerable<KeyValuePair<string, string>> AsKVP(
        this NameValueCollection source
)
{
    return source.AllKeys.SelectMany(
        source.GetValues,
        (k, v) => new KeyValuePair<string, string>(k, v));
}

तो आप कर सकते हैं:

NameValueCollection nv = HttpUtility.ParseQueryString(queryString);
foreach (KeyValuePair<String,String> pr in nv.AsKVP()) {
    //process KeyValuePair          
}

नोट: से प्रेरित इस । डुप्लिकेट कुंजियों को संभालने के लिए SelectMany की आवश्यकता होती है।

vb.net संस्करण:

<Extension>
Public Function AsKVP(
        source As Specialized.NameValueCollection
) As IEnumerable(Of KeyValuePair(Of String, String))
    Dim result = source.AllKeys.SelectMany(
        AddressOf source.GetValues,
        Function(k, v) New KeyValuePair(Of String, String)(k, v))
    Return result
End Function

10

भविष्य के संदर्भ के लिए, आप इस वाक्यविन्यास का उपयोग भी कर सकते हैं:

foreach(string key in Request.QueryString)
{
    var value = Request.QueryString[key];
}

2
कुंआ। यदि आप के पास पहुँच है तो HttpRequestआप छोड़ सकते हैं AllKeysक्योंकि QueryStringसंपत्ति एक है NameValueCollection।
— jgauffin

-1 आप का उपयोग करने की आवश्यकता नहीं है क्योंकि AllKeysउल्लेख @jgauffin के रूप में
— करामाती

@Arlock: इसके लिए -1 देना थोड़ा कठोर है। आप उत्तर को संपादित कर सकते हैं, क्या आप नहीं कर सकते?
— jgauffin

हां, इसके लिए खेद है, मैं किसी को चोट नहीं पहुंचाना चाहता था :) लेकिन समस्या केवल संपत्ति में नहीं थी। यदि आप @ jgauffin के उत्तर को देखते हैं, तो उन्होंने एक ही विचार प्रस्तावित किया था, लेकिन यह पहले पोस्ट किया गया था। तो, यह पोस्ट एक दोहराव की तरह लग रहा है।
— वारलॉक

यदि आप मेरे द्वारा लिखी गई अंतिम टिप्पणी को देखते हैं jgauffinऔर यदि आप करीब से देखते हैं तो उत्तर डुप्लिकेट नहीं हैं।
— jgauffin

6

अधिगम विस्तार विधि, सीखने के उद्देश्यों के लिए:

    public static IEnumerable<KeyValuePair<string, string>> ToIEnumerable(this NameValueCollection nvc)
    {
        foreach (string key in nvc.AllKeys)
        {
            yield return new KeyValuePair<string, string>(key, nvc[key]);
        }
    }

अच्छा समाधान! मैं nvcइसके बजाय उपयोग करने का सुझाव दूंगा nvc.AllKeys। मैं सोच रहा था कि Microsoft लोग इसे क्यों नहीं जोड़ रहे हैं System.Linq। :)
— वॉरलॉक

2

NameValueCollection पुराने-स्कुल एन्यूमरेटर का उपयोग करता है:

        var enu = ConfigurationManager.AppSettings.GetEnumerator();

        while(enu.MoveNext())
        {
            string key = (string)enu.Current;
            string value = ConfigurationManager.AppSettings[key];
        }

0

मुझे यह पसंद आया और यह काम करता है:

 foreach (string akey in request.Query.Keys.Cast<string>())
     writer.WriteLine(akey + " = " + request.Query[akey]);

0

ज्ञात हो कि कुंजी नाम क्वेरी स्ट्रिंग में एक से अधिक बार दिखाई दे सकता है और यह कि तुलना आमतौर पर संवेदनशील होती है।
यदि आप पहली मिलान कुंजी का मूल्य प्राप्त करना चाहते हैं और मामले से परेशान नहीं हैं तो इसका उपयोग करें:

        public string GetQueryValue(string queryKey)
        {
            foreach (string key in QueryItems)
            {
                if(queryKey.Equals(key, StringComparison.OrdinalIgnoreCase))
                    return QueryItems.GetValues(key).First(); // There might be multiple keys of the same name, but just return the first match
            }
            return null;
        }

-1
public static void PrintKeysAndValues2( NameValueCollection myCol )
{
    Console.WriteLine( "   [INDEX] KEY        VALUE" );
    for ( int i = 0; i < myCol.Count; i++ )
        Console.WriteLine( "   [{0}]     {1,-10} {2}", i, myCol.GetKey(i), myCol.Get(i) );
    Console.WriteLine();
}

http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx


-1 आप दिखाते हैं कि NameValueCollectionडेटा तक पहुंचने के लिए इसका उपयोग करना संभव है । लेकिन सवाल यह है कि आप NameValueCollectionआइटम को क्यों नहीं बदल सकते हैं KeyValuePair<string, string>। हो सकता है कि आप प्रश्न को बहुत ध्यान से पढ़ें। द्वारा सबसे अच्छा जवाब दिया गया था jgauffin। द्वारा एक दिलचस्प समाधान प्रस्तावित किया गया था Adrian Carneiro।
— वॉरलॉक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.