我有一個序列化到DataContractJsonSerializer存儲的字典,我想用Newtonsoft.Json反序列化。Newtonsoft Json反序列化字典作爲DataContractJsonSerializer的鍵/值列表
的DataContractJsonSerializer已序列化的字典鍵/值對的列表:
{"Dict":[{"Key":"Key1","Value":"Val1"},{"Key":"Key2","Value":"Val2"}]}
是否有冷靜的選擇,我可以給JsonConvert.DeserializeObject<>()
,這將使它支持的數據格式和Newtonsoft格式以.json?
{"Dict":{"Key1":"Val1","Key2":"Val2"}}
是漂亮的格式Newtonsoft.Json創造,我想能夠同時讀取舊DataContract格式,並在過渡期的新Newtonsoft格式。
簡單的例子:
//[JsonArray]
public sealed class Data
{
public IDictionary<string, string> Dict { get; set; }
}
[TestMethod]
public void TestSerializeDataContractDeserializeNewtonsoftDictionary()
{
var d = new Data
{
Dict = new Dictionary<string, string>
{
{"Key1", "Val1"},
{"Key2", "Val2"},
}
};
var oldJson = String.Empty;
var formatter = new DataContractJsonSerializer(typeof (Data));
using (var stream = new MemoryStream())
{
formatter.WriteObject(stream, d);
oldJson = Encoding.UTF8.GetString(stream.ToArray());
}
var newJson = JsonConvert.SerializeObject(d);
// [JsonArray] on Data class gives:
//
// System.InvalidCastException: Unable to cast object of type 'Data' to type 'System.Collections.IEnumerable'.
Console.WriteLine(oldJson);
// This is tha data I have in storage and want to deserialize with Newtonsoft.Json, an array of key/value pairs
// {"Dict":[{"Key":"Key1","Value":"Val1"},{"Key":"Key2","Value":"Val2"}]}
Console.WriteLine(newJson);
// This is what Newtonsoft.Json generates and should also be supported:
// {"Dict":{"Key1":"Val1","Key2":"Val2"}}
var d2 = JsonConvert.DeserializeObject<Data>(newJson);
Assert.AreEqual("Val1", d2.Dict["Key1"]);
Assert.AreEqual("Val2", d2.Dict["Key2"]);
var d3 = JsonConvert.DeserializeObject<Data>(oldJson);
// Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into
// type 'System.Collections.Generic.IDictionary`2[System.String,System.String]' because the type requires a JSON
// object (e.g. {"name":"value"}) to deserialize correctly.
//
// To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type
// to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be
// deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from
// a JSON array.
//
// Path 'Dict', line 1, position 9.
Assert.AreEqual("Val1", d3.Dict["Key1"]);
Assert.AreEqual("Val2", d3.Dict["Key2"]);
}
謝謝你,完美的工作! (我用TypeConverter進行了實驗,但沒有成功,但是這樣做:) – 2015-02-12 09:06:45