Vro*_*del 15 .net oop serialization multiple-interface-implem datacontractjsonserializer
我有一个对象树,我正在序列化为JSON DataContractJsonSerializer
.Dictionary<TKey, TValue>
得到序列化但我不喜欢标记 - 项目不会像这样呈现:
{key1:value, key2:value2}
Run Code Online (Sandbox Code Playgroud)
而是像一系列序列化KeyValuePair<TKey, TValue>
对象:
[{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key1",
"value":"value1"
},
{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key2",
"value":"value2"
}]
Run Code Online (Sandbox Code Playgroud)
丑,不是吗?
因此,我通过将通用Dictionary包装在实现的自定义对象中来避免这种情况ISerializable
,并且我在GetObjectData
方法中实现了自定义序列化(并且它只需要3行).
现在的问题-我不能让我的类从派生Dictionary<TKey, TValue>
,所以我实现所有的逻辑(Add
,Clear
,等),在我的自定义类,被应用到私人Dictionary<TKey, TValue>
领域.继承会更好,因为在使用我的自定义对象时,我将拥有所有通用字典功能.
继承的问题是它自己的Dictionary<TKey, TValue>
实现ISerializable
,并且DataContractJsonSerializer
似乎更喜欢这个实现,即使我ISerializable
从我的自定义类显式实现,如下所示:
public class MyClass : Dictionary<string, object>, ISerializable
{
public override void GetObjectData(SerializationInfo info,
StreamingContext context)
}
Run Code Online (Sandbox Code Playgroud)
我真的很惊讶这是可能的,因为它允许我实现相同的接口两次而不显然能够使用显式接口实现 - 所以我在一篇关于多接口实现的博客文章中更详细地分析了这种情况
所以,根据我在那里做的实验,序列化器应该调用我的ISerializable实现,无论内部使用什么类型的转换 -
((ISerializable)((Dictionary<,>)obj)).GetObjectData(...)
Run Code Online (Sandbox Code Playgroud)
要么:
((ISerializable)obj).GetObjectData(...)
Run Code Online (Sandbox Code Playgroud)
但它显然没有发生,因为我在生成的JSON中看到KeyValuePair<TKey, TValue>
序列化器仍然被调用.我错过了可能发生的事情?
更新:到目前为止我得到的答案和评论几乎只是建议解决方法.然而,我注意到,我有一个非常好的解决方法,所以在问这个问题时我有两个目标:
最终使它与原始设计一起工作 - 我不会仅仅为此更改序列化逻辑,有很多代码和逻辑依赖于它
为了解释为什么不DataContractJsonSerializer
使用我的序列化代码的谜团- 正如我在上面提到的博客文章中看到的那样,我已经用接口实现和继承进行了各种实验,我相信我正在抓住所有的ins这个过程的结束,所以我很难理解在这种情况下有什么好处
看来,没有办法自定义DataContractJsonSerializer。
如果您仍然想实现您想要的目标,请考虑使用Json.Net。它比 DataContractJsonSerializer 更快、更灵活。看看 Json.Net 的 JsonConverter 概念。它使您可以自定义序列化/反序列化过程。
此外,字典序列化的默认实现完全符合您的要求http://james.newtonking.com/projects/json/help/SerializingCollections.html。