2011-08-09 20 views

回答

34

NameValueCollection不是一個IDictionary,所以JavaScriptSerializer不能像你期望的那樣直接序列化它。您需要先將其轉換爲字典,然後將其序列化。

更新:以下有關每個鍵的多個值的問題,撥打nvc[key]將簡單地將它們返回,用逗號分隔,這可能沒問題。如果沒有,可以隨時撥打GetValues並決定如何處理這些值。更新下面的代碼以顯示一種可能的方式。

public class StackOverflow_7003740 
{ 
    static Dictionary<string, object> NvcToDictionary(NameValueCollection nvc, bool handleMultipleValuesPerKey) 
    { 
     var result = new Dictionary<string, object>(); 
     foreach (string key in nvc.Keys) 
     { 
      if (handleMultipleValuesPerKey) 
      { 
       string[] values = nvc.GetValues(key); 
       if (values.Length == 1) 
       { 
        result.Add(key, values[0]); 
       } 
       else 
       { 
        result.Add(key, values); 
       } 
      } 
      else 
      { 
       result.Add(key, nvc[key]); 
      } 
     } 

     return result; 
    } 

    public static void Test() 
    { 
     NameValueCollection nvc = new NameValueCollection(); 
     nvc.Add("foo", "bar"); 
     nvc.Add("multiple", "first"); 
     nvc.Add("multiple", "second"); 

     foreach (var handleMultipleValuesPerKey in new bool[] { false, true }) 
     { 
      if (handleMultipleValuesPerKey) 
      { 
       Console.WriteLine("Using special handling for multiple values per key"); 
      } 
      var dict = NvcToDictionary(nvc, handleMultipleValuesPerKey); 
      string json = new JavaScriptSerializer().Serialize(dict); 
      Console.WriteLine(json); 
      Console.WriteLine(); 
     } 
    } 
} 
+3

'NameValueCollection'每個鍵可以有多個值,這不能解決這個問題。 – zzzzBov

+0

此方法可能會導致異常! NameValueCollection存在(以及.NET有時不使用字典)的原因是爲每個鍵允許多個值。字典僅需要每個值一個鍵。 –

+1

該方法不會拋出異常。如果有多個鍵,'nvc [key]'只會返回由'','字符連接的鍵。但爲了完整起見,我更新了答案,以便更清楚地瞭解它。 – carlosfigueira

3

如果你的字典裏不打算包含許多條目,可以使用類: System.Collections.Specialized.ListDictionary序列化NameValueCollection中時,首先將其轉換成字典,

33

的一種方式序列化字典。要轉換到詞典:

thenvc.AllKeys.ToDictionary(k => k, k => thenvc[k]); 

如果你需要頻繁地進行轉換,也可以創建一個擴展方法的NameValueCollection:

public static class NVCExtender 
{ 
    public static IDictionary<string, string> ToDictionary(
             this NameValueCollection source) 
    { 
     return source.AllKeys.ToDictionary(k => k, k => source[k]); 
    } 
} 

所以你可以做轉換在這樣一行:

NameValueCollection Data = new NameValueCollection(); 
Data.Add("Foo", "baa"); 

var dict = Data.ToDictionary(); 

然後你可以序列化的詞典:

var json = new JavaScriptSerializer().Serialize(dict); 
// you get {"Foo":"baa"} 

但NameValueCollection中可以有多個值的一個關鍵,例如:

NameValueCollection Data = new NameValueCollection(); 
Data.Add("Foo", "baa"); 
Data.Add("Foo", "again?"); 

如果序列化此你會得到{"Foo":"baa,again?"}

您可以修改轉換器產生IDictionary<string, string[]>代替:

public static IDictionary<string, string[]> ToDictionary(
            this NameValueCollection source) 
{ 
    return source.AllKeys.ToDictionary(k => k, k => source.GetValues(k)); 
} 

這樣你就可以得到這樣的序列化值:{"Foo":["baa","again?"]}