Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET Serialize private members and not readonly properties

Tags:

c#

json.net

How can I customize Json.NET to serialize private members and NOT serialize public readonly properties (without using attributes).

I've had a stab around at creating a custom IContractResolver but am a bit lost.

like image 955
Ben Foster Avatar asked Apr 17 '12 10:04

Ben Foster


People also ask

Does JSON net serialize private fields?

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.

How to ignore some properties in Json?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

Which of the following attribute should be used to indicate the property must not be serialized while using JSON serializer?

Apply a [JsonIgnore] attribute to the property that you do not want to be serialized. Add an alternate, private property setter to the class with the same type as the original property. Make the implementation of that property set the original property.

What is JsonSerializerSettings?

Specifies the settings on a JsonSerializer object. Newtonsoft.Json. JsonSerializerSettings. Namespace: Newtonsoft.Json.


2 Answers

For a partial answer, messing with DefaultContractResolver.DefaultMembersSearchFlags can get it to include private things:

Newtonsoft.Json.JsonSerializerSettings jss = new Newtonsoft.Json.JsonSerializerSettings();

if (includePrivateMembers)
{
    Newtonsoft.Json.Serialization.DefaultContractResolver dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver();
    dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
    jss.ContractResolver = dcr;
}

return Newtonsoft.Json.JsonConvert.SerializeObject(o, jss);

Seems to work on a lot of objects, though with some this seems to generate a CLR exception.

like image 82
Chris Avatar answered Oct 21 '22 23:10

Chris


In response to Chris' answer, the DefaultMemberSearchFlags property on DefaultContractResolver was deprecated as of version 6. Despite of what the deprecation message says, I believe you'll need to overwrite the CreateProperties method, too, like L.B explains.

This method gives you full control, including excluding readonly properties:

class PrivateContractResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        MemberInfo[] fields = objectType.GetFields(flags);
        return fields
            .Concat(objectType.GetProperties(flags).Where(propInfo => propInfo.CanWrite))
            .ToList();
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
           return base.CreateProperties(type, MemberSerialization.Fields);
    }           
}
like image 33
tm1 Avatar answered Oct 21 '22 23:10

tm1