【问题标题】:Why does [Serializable] cause Newtonsoft.Json serializer to include backing fields?为什么 [Serializable] 会导致 Newtonsoft.Json 序列化程序包含支持字段?
【发布时间】:2019-08-19 12:31:27
【问题描述】:

如果我在一个类上有 [Serializable] 属性,那么它会导致生成的序列化 Json 字符串包含框架创建的支持成员。

例如,我的 Id 字段如下所示:

<Id>k__BackingField=20001  

我可以在 SOF 和其他地方找到许多资源来解决这个问题,但我找不到为什么 Json 序列化程序在看到 [Serializable] 属性时表现不同。

如果 Jason 序列化程序不序列化成员而只序列化属性,那么为什么当使用 [Serializable] 属性修饰类时它的行为会有所不同?

请注意,我不是在寻找解决此问题的方法,因为我已经找到了。我想知道为什么 Newtonsoft.Jsonserializer 在这里表现不同。

【问题讨论】:

  • 来自Serialization Guide: Objects最后,可以使用字段模式对类型进行序列化。所有字段,无论是公共的还是私有的,都被序列化并且属性被忽略。这可以通过在具有 JsonObjectAttribute 的类型上设置 MemberSerialization.Fields 或使用 .NET SerializableAttribute 并将 DefaultContractResolver 上的 IgnoreSerializableAttribute 设置为 false 来指定。
  • 所以你的代码必须在某处设置DefaultContractResolver.IgnoreSerializableAttribute = false;这不是默认设置。这能回答你的问题吗?
  • 或者等待:&lt;Id&gt;k__BackingField=20001 看起来像 XML 而不是 JSON。你确定你使用的是json.net吗?你能分享minimal reproducible example吗?如果您实际使用DataContractSerializer,您可以获得这些支持字段,请参阅Is there a way to make DataContractSerializer output cleaner XML? 了解原因。
  • @dbc 我正在研究的解决方案使用 WCF 和 Web API,就像你说的设置 IgnoreSerializableAttribute 设置已经解决了问题。我问了这个问题,因为我找不到 Json.net 的行为方式。感谢您提供的链接(序列化指南:对象)我现在明白了。谢谢。

标签: json.net serializable


【解决方案1】:

如果以后有人想找到原因,下面解释一下Json.Net是如何序列化对象的:

Breakdown of Type Serialization > Objects

默认情况下,类型的属性以选择退出模式进行序列化。什么 这意味着所有带有 getter 的公共字段和属性都是 自动序列化为 JSON,以及字段和属性 不应该被序列化通过放置 JsonIgnoreAttribute 来选择退出 在他们。要序列化私有成员,JsonPropertyAttribute 可以 放置在私有字段和属性上。

类型也可以使用选择加入模式进行序列化。只有属性和 具有 JsonPropertyAttribute 或 DataMemberAttribute 的字段 它们将被序列化。对象的选择加入模式由 将 JsonObjectAttribute 或 DataContractAttribute 放在类型上。

最后,可以使用字段模式对类型进行序列化。所有领域,两者 公共和私有,被序列化并且属性被忽略。这 可以通过在类型上设置 MemberSerialization.Fields 来指定 JsonObjectAttribute 或使用 .NET SerializableAttribute 和 将 DefaultContractResolver 上的 IgnoreSerializableAttribute 设置为 假的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2011-12-04
    • 2020-06-19
    • 1970-01-01
    相关资源
    最近更新 更多