foreach KeyValuePair in NameValueCollection?


79

Ich habe diesen Code:

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

Dies wird kompiliert, aber wenn ich versuche, es auszuführen, bekomme ich eine InvalidCastException.

Warum ist das? Warum kann ich nicht KeyValuePairüber a iterieren NameValueCollectionund was soll ich stattdessen verwenden?


Ich mag dies, da ich ein Wörterbuch initiieren kann, ohne zusätzlich zu einem foreach eine Hintergrundwörterbuchvariable erstellen zu müssen. var nv = HttpUtility.ParseQueryString(Request.Url.Query); var qsDic = nv.Cast<object>().ToDictionary<object, string, object>(key => (string) key, key => nv[(string) key]);
— Der Muffin-Mann

Antworten:


129

Erstens NameValueCollectionnicht verwendet KeyValuePair<String,String>. Außerdem wird foreachnur der Schlüssel angezeigt:

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

}

3
Hmm, das ist irgendwie komisch. Ich hätte erwartet, dass es einen Weg gibt, beides gleichzeitig zu bekommen.
— Oliver

26
Wir alle tun dies, wenn wir einen NVC verwenden.
— Jgauffin

1
Ich habe mich gefragt, wie das geht ... danke! Übrigens müssen Sie nicht angeben, KeyValuePair<String,String>da die NameValueCollection nur Zeichenfolge, Zeichenfolge verwendet. Keine Notwendigkeit, es anzugeben.
— TheGateKeeper

7
Beachten Sie, wie dieser Code für doppelte Schlüssel funktioniert. Wenn doppelte Schlüssel vorhanden sind, wird "Schlüsselwert1, Wert2, Wert3" anstelle von "Schlüsselwert1", dann "Schlüsselwert2" und "Schlüsselwert3" zurückgegeben.
— Doug S

3
@Nick: NameValueCollection ist einer der ersten Sammlungstypen in .NET. Es unterscheidet nicht zwischen Groß- und Kleinschreibung und führt vorhandene Werte zusammen (was für einige Protokolle nützlich ist)
— jgauffin

11

Sie können das nicht direkt tun, aber Sie können eine Erweiterungsmethode wie folgt erstellen:

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

Dann können Sie tun:

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

Hinweis: inspiriert durch diese . SelectMany ist erforderlich, um doppelte Schlüssel zu verarbeiten.

vb.net Version:

<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

Zum späteren Nachschlagen können Sie auch diese Syntax verwenden:

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

2
Gut. Wenn Sie Zugriff auf die haben HttpRequest, können Sie überspringen, AllKeysda die QueryStringEigenschaft eine ist NameValueCollection.
— Jgauffin

-1, weil Sie nicht AllKeyswie @jgauffin erwähnt verwenden müssen
— Warlock

@ Warlock: Eine -1 dafür zu geben ist ein bisschen hart. Sie können die Antwort bearbeiten, nicht wahr?
— Jgauffin

Ja, tut mir leid, ich wollte niemanden verletzen :) Aber das Problem lag nicht nur auf dem Grundstück. Wenn Sie sich die Antwort von @ jgauffin ansehen, schlug er dieselbe Idee vor, die jedoch früher veröffentlicht wurde. Dieser Beitrag sieht also wie eine Vervielfältigung aus.
— Hexenmeister

Wenn Sie sich den letzten Kommentar ansehen, der von mir geschrieben wurde, sind jgauffindie Antworten keine Duplikate, wenn Sie genauer hinschauen.
— Jgauffin

6

Eine andere Erweiterungsmethode für Lernzwecke:

    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]);
        }
    }

Schöne Lösung! Ich würde nur vorschlagen, nvcstatt zu verwenden nvc.AllKeys. Ich frage mich, warum Microsoft-Leute dies nicht hinzugefügt haben System.Linq. :)
— Hexenmeister

2

NameValueCollection verwendet den Old-Skool-Enumerator:

        var enu = ConfigurationManager.AppSettings.GetEnumerator();

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

0

Mir hat das gefallen und es funktioniert:

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

0

Beachten Sie, dass der Schlüsselname möglicherweise mehrmals in der Abfragezeichenfolge vorkommt und dass beim Vergleich normalerweise zwischen Groß- und Kleinschreibung unterschieden wird.
Wenn Sie nur den Wert des ersten passenden Schlüssels erhalten möchten und sich nicht um die Groß- und Kleinschreibung kümmern möchten, verwenden Sie Folgendes:

        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 Sie zeigen, dass der Zugriff auf NameValueCollectionDaten möglich ist. Die Frage ist jedoch, warum Sie keine NameValueCollectionElemente in konvertieren können KeyValuePair<string, string>. Vielleicht haben Sie die Frage nicht sehr sorgfältig gelesen. Die beste Antwort wurde von gegeben jgauffin. Eine interessante Lösung wurde von vorgeschlagen Adrian Carneiro.
— Hexenmeister
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.