Json.Net – 将字典序列化为数组(键值对)

Json.Net通常将Dictionary<k,v>序列化为一个集合;

 "MyDict": { "Apples": { "Taste": 1341181398, "Title": "Granny Smith", }, "Oranges": { "Taste": 9999999999, "Title": "Coxes Pippin", }, } 

这是伟大的。 而从环顾四周,这似乎是大多数人想要的。 然而,在这种特殊情况下,我想序列化我的Dictionary<k,v>和Array格式。

 "MyDict": [ "k": "Apples", "v": { "Taste": 1341181398, "Title": "Granny Smith", } }, "k:": "Oranges", "v:": { "Taste": 9999999999, "Title": "Coxes Pippin", } }, ] 

有一个简单的方法来做到这一点与我现有的字段types? 是否有一个我可以注释的属性?

另一种方法是使用自定义ContractResolver 。 这样,您不必在每次序列化时都inheritanceDictionary<K,V>子类Dictionary<K,V>也不会像其他答案中所build议的那样应用转换。

以下parsing器将使所有字典被序列化为具有“Key”和“Value”属性的对象数组:

 class DictionaryAsArrayResolver : DefaultContractResolver { protected override JsonContract CreateContract(Type objectType) { if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) || (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>)))) { return base.CreateArrayContract(objectType); } return base.CreateContract(objectType); } } 

要使用parsing器,将它添加到您的JsonSerializerSettings ,然后将设置传递给JsonConvert.SerializeObject()像这样:

 JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new DictionaryAsArrayResolver(); string json = JsonConvert.SerializeObject(obj, settings); 

这是一个工作演示 。

啊,事实certificate,这和我所希望的一样简单。 我的Dictionary<k,v>已经被子类化,我发现我可以用[JsonArrayAttribute]对它进行注释。 这给了我完全我需要的格式;

 "MyDict": [ { "Key": "Apples", "Value": { "Taste": 1341181398, "Title": "Granny Smith", } }, { "Key:": "Oranges", "Value:": { "Taste": 9999999999, "Title": "Coxes Pippin", } }, ] 

对于这个例子,我将使用dictonary:

 var myDict = new Dictionary<string,string>() { {"a","123"}, {"b","234"}, {"c","345"} }; 

(使用Newtonsoft.Json.JsonConvert.SerializeObject(myDict) )序列化到:

 {"a":"123","b":"234","c":"345"} 

你可以使用LINQ来创build一个匿名对象,然后序列化:

  var myDictTransformed = from key in myDict.Keys select new { k = key, v = myDict[key] }; 

或者你可以使用一个真实的物体

 class MyDictEntry { public string k { get; set; } public string v { get; set; } } 

以及上面的或替代的LINQ语法:

 var myDictTransformed = myDict.Keys.AsEnumerable() .Select(key => new MyDictEntry{ k = key, v = myDict[key] }); 

无论哪种方式,这个序列化为:

 [ {"k":"a", "v":"123"}, {"k":"b", "v":"234"}, {"k":"c", "v":"345"} ] 

.NET小提琴链接: https : //dotnetfiddle.net/LhisVW

我find的最简单的解决scheme是将您的Dictionary<string, string>转换为List<KeyValuePair<string, string>> 。 然后,JSON.NET将你的List转换成{ Key: 'keyname', Value: 'value' }forms的对象数组。 如果您接受所需的模型更改并且不希望子类化您的Dictionary这很好。

gregmac的答案是有帮助的,但没有完全奏效。 以下是相同的想法…没有双关语。

 var dictionaryTransformed = dictionary.Select(item => item.Key).Select(i => new {Key = i, Value = dictionary[i] }); 

或者当然

 var dictionaryTransformed = dictionary.Select(item => new {item.Key, Value = dictionary[item.Key] }); 

然后去json

 var json = (new JavaScriptSerializer()).Serialize( new { Container = dictionaryTransformed.ToArray() } )