问题描述
是否可以使用Json.NET进行反序列化,但继续使用DataContractJsonSerializer
的字典序列化约定?
Is there a way to use Json.NET for (de)serialization but continue to use the dictionary serialization conventions of DataContractJsonSerializer
?
换句话说,有没有一种方法可以在这种结构中读取和写入JSON:
In other words, is there a way to read and write JSON in this structure:
{ "MyDict" : [
{ "Key" : "One",
"Value" : 1 },
{ "Key" : "Two",
"Value" : 2 }
] }
使用这样的类(具有Json.NET属性):
Using a class like this (with Json.NET attributes):
public class MyClass
{
public Dictionary<string, int> MyDict { get; set; }
}
似乎Json.NET的KeyValuePairConverter
可能以某种方式有所帮助,但如果是这样,我找不到正确的应用方式.
It seems like Json.NET's KeyValuePairConverter
might help somehow, but if so, I can't find the correct way to apply it.
我尝试将MyDict
归于[JsonProperty(ItemConverterType = typeof(KeyValuePairConverter))]
,此页面甚至似乎暗示着可能有效,但是添加这样的属性会在序列化期间导致ArgumentOutOfRangeException
.
I tried attributing MyDict
with [JsonProperty(ItemConverterType = typeof(KeyValuePairConverter))]
, this page even seems to imply that could work, but adding such an attribute results in an ArgumentOutOfRangeException
during serialization.
推荐答案
是的,KeyValuePairConverter
在这里似乎无法正常工作.在不深入研究Json.Net源代码的情况下,我只能推测原因.解决方法是,您可以制作自己的自定义JsonConverter
来轻松完成此翻译:
You're right, the KeyValuePairConverter
doesn't seem to work correctly here. Without digging into the Json.Net source code, I can only speculate as to why. As a workaround, you can make your own custom JsonConverter
to do this translation quite easily:
class MyDictionaryConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Dictionary<string, T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray array = JArray.Load(reader);
Dictionary<string, T> dict = new Dictionary<string, T>();
foreach (JObject obj in array.Children<JObject>())
{
string key = obj["Key"].ToString();
T val = obj["Value"].ToObject<T>();
dict.Add(key, val);
}
return dict;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Dictionary<string, T> dict = (Dictionary<string, T>)value;
JArray array = new JArray();
foreach (KeyValuePair<string, T> kvp in dict)
{
JObject obj = new JObject();
obj.Add("Key", kvp.Key);
obj.Add("Value", JToken.FromObject(kvp.Value));
array.Add(obj);
}
array.WriteTo(writer);
}
}
使用[JsonConverter]
属性将转换器应用于字典:
Apply the converter to the dictionary using a [JsonConverter]
attribute:
public class MyClass
{
[JsonConverter(typeof(MyDictionaryConverter<int>))]
public Dictionary<string, int> MyDict { get; set; }
}
下面是一个简短的演示程序,显示了转换器的运行情况(完整往返):
Here is a short demo program showing the converter in action (full round trip):
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass { MyDict = new Dictionary<string, int>() };
mc.MyDict.Add("One", 1);
mc.MyDict.Add("Two", 2);
string json = JsonConvert.SerializeObject(mc, Formatting.Indented);
Console.WriteLine(json);
Console.WriteLine();
MyClass mc2 = JsonConvert.DeserializeObject<MyClass>(json);
foreach (KeyValuePair<string, int> kvp in mc2.MyDict)
{
Console.WriteLine(kvp.Key + " == " + kvp.Value);
}
}
}
以上内容的输出
{
"MyDict": [
{
"Key": "One",
"Value": 1
},
{
"Key": "Two",
"Value": 2
}
]
}
One == 1
Two == 2
这篇关于使用Json.NET在DataContractJsonSerializer使用的结构中对字典进行反序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!