Search code examples
json.netserializable

Why does [Serializable] cause Newtonsoft.Json serializer to include backing fields?


If I have [Serializable] attribute on a class then it causes the resulting serialised Json string to include backing members created by the framework.

For example I get below for my Id field:

<Id>k__BackingField=20001  

I could find many resources on SOF and elsewhere to get around this problem but I couldn't find why Json serializer is behaving differently when it sees [Serializable] attribute.

If the Jason serializer doesn't serialise members and only serialise properties then why does it behave differently when a class is decorated with [Serializable] attribute?

Please note I'm not looking for a way to fix this issue as I have already found that. I would like to know why Newtonsoft.Jsonserialiser behaves differently here.


Solution

  • In case someone wants to find the reason in the future, following explains how objects are serialised by Json.Net:

    Breakdown of Type Serialization > Objects

    By default a type's properties are serialized in opt-out mode. What that means is that all public fields and properties with getters are automatically serialized to JSON, and fields and properties that shouldn't be serialized are opted-out by placing JsonIgnoreAttribute on them. To serialize private members, the JsonPropertyAttribute can be placed on private fields and properties.

    Types can also be serialized using opt-in mode. Only properties and fields that have a JsonPropertyAttribute or DataMemberAttribute on them will be serialized. Opt-in mode for an object is specified by placing the JsonObjectAttribute or DataContractAttribute on the type.

    Finally, types can be serialized using a fields mode. All fields, both public and private, are serialized and properties are ignored. This can be specified by setting MemberSerialization.Fields on a type with the JsonObjectAttribute or by using the .NET SerializableAttribute and setting IgnoreSerializableAttribute on DefaultContractResolver to false.