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.