NameValueCollection의 foreach KeyValuePair?


79

이 코드가 있습니다.

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

이것은 컴파일되지만 실행하려고 할 때 InvalidCastException.

왜 이런거야? KeyValuePair을 반복 하는 데 사용할 수없는 이유는 NameValueCollection무엇이며 대신 무엇을 사용해야합니까?


foreach 외에도 백업 사전 변수를 만들지 않고도 사전을 초기화 할 수 있으므로 이것을 좋아합니다. var nv = HttpUtility.ParseQueryString(Request.Url.Query); var qsDic = nv.Cast<object>().ToDictionary<object, string, object>(key => (string) key, key => nv[(string) key]);
The Muffin Man

답변:


133

우선, NameValueCollection사용하지 않습니다 KeyValuePair<String,String>. 또한 foreach키만 노출합니다.

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

}

3
흠, 좀 이상 해요. 한 번에 두 가지를 모두 얻을 수있는 방법이있을 것으로 예상 했었습니다.
Oliver

27
우리 모두는 NVC를 사용하기 시작할 때합니다.
jgauffin 2011

1
어떻게하는지 궁금해서 ... 감사합니다! Btw, KeyValuePair<String,String>NameValueCollection이 문자열, 문자열 만 사용하므로 지정할 필요가 없습니다 . 지정할 필요가 없습니다.
TheGateKeeper

7
이 코드가 중복 키에 대해 어떻게 작동하는지 확인하십시오. 중복 키가있는 경우 "key value1", "key value2", "key value3"대신 "key value1, value2, value3"을 반환합니다.
Doug S

3
@Nick : NameValueCollection은 .NET의 첫 번째 컬렉션 유형 중 하나입니다. 대소 문자를 구분하지 않고 기존 값을 병합합니다 (일부 프로토콜에 유용함)
jgauffin 2013-09-25

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는 AS QueryString속성이 있습니다 NameValueCollection.
jgauffin

-1 당신은 사용하지 않기 때문에 AllKeys언급 @jgauffin로
흑 마법사

@Warlock : -1을주는 것은 약간 가혹합니다. 답을 수정할 수 있지 않나요?
jgauffin 2014-07-26

네, 죄송합니다. 누구도 다치게하고 싶지 않았습니다. :) 그러나 문제는 부동산에만있는 것이 아닙니다. @jgauffin의 답변을 보면 그는 같은 아이디어를 제안했지만 이전에 게시되었습니다. 따라서이 게시물은 중복 된 것처럼 보입니다.
Warlock

마지막 댓글을 보시면 저가 쓴 jgauffin것이고 자세히 보면 답이 중복되지 않습니다.
jgauffin 2014-07-26

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 사람들이 이것을 .NET에 추가하지 않았는지 궁금 System.Linq합니다. :)
흑 마법사

2

NameValueCollection은 old-skool 열거자를 사용합니다.

        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데이터 에 액세스하기 위해 for를 사용할 수 있음을 보여줍니다 . 그러나 문제는 왜 NameValueCollection항목을 KeyValuePair<string, string>. 질문을주의 깊게 읽지 않았을 수도 있습니다. 가장 좋은 답변은 jgauffin. 에서 흥미로운 솔루션을 제안했습니다 Adrian Carneiro.
Warlock
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.