Serializing private fields with JSON.NET and GetSerializableMembers

JSON.NET can handle serializing and deserializing private fields, but you have to tell it to do so.

In the past, you had to set the DefaultMembersSearchFlags property of the ContractResolver of your settings. But this property is now marked obsolete. The documentation/Intellisense tells you to override GetSerializableMembers instead.

But I've found there's just one extra step involved.

First thing to do is to create your own class that inherits from DefaultContractResolver and override the GetSerializableMembers method:

protected override List<MemberInfo> GetSerializableMembers(Type objectType)  
{
    var result = base.GetSerializableMembers(objectType);

    if (objectType  typeof(MyClass))
    {    
        var memberInfo = objectType.GetMember("_myField", 
                BindingFlags.NonPublic | BindingFlags.Instance).Single();
        result.Add(memberInfo);
    }

    return result;
}

This will make sure JSON.NET serializes the private field, but it didn't seem to deserialize it in my case. The solution is to also override the CreateProperties method and set the property as... Readeable.

Curiously enough, you have to set the property as Readable, not Writeable. If anyone knows why, feel free to let me know (I have no time now to check the source).

Anyway, this is more or less what my code looks like now:

protected override IList<jsonproperty> CreateProperties(Type type, MemberSerialization memberSerialization)  
{
    var properties = base.CreateProperties(type, memberSerialization);

    if (type  typeof(MyClass))
    {
        var property = properties.Single(x => 
                 x.PropertyName  "_myField" 
                 && x.DeclaringType  member.DeclaringType);
        property.Readable = true;
    }

    return properties;
}