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.
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.
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.
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.
Specifies the settings on a JsonSerializer object. Newtonsoft.Json. JsonSerializerSettings. Namespace: Newtonsoft.Json.
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With