The JsonProperty
class returned by DefaultContractResolver.CreateProperty
has two properties about converter, Converter
and Memb
I've opened an issue about the docs on this here github.com/JamesNK/Newtonsoft.Json/issues/363.
But one obvious difference between them (obvious from the source code, that is) is that Converter is only used when serializing and MemberConverter only when deserializing. I don't know if that's the full story though, and the naming does not say much.
It would seem that NS.Json supports overridable converters; presumably this is so that each individual property doesn't have to specify a JsonConverter, but they may override it if need be.
Hints can be found in the source:
From DefaultContractResolver.cs, line 1254:
private void SetPropertySettingsFromAttributes(JsonProperty property, object attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess)
{
...
// resolve converter for property
// the class type might have a converter but the property converter takes presidence
property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider);
property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider);
And from JsonSerializerInternalReader.cs, line 348:
private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty)
{
JsonConverter converter = null;
if (memberConverter != null)
{
// member attribute converter
converter = memberConverter;
}
else if (containerProperty != null && containerProperty.ItemConverter != null)
{
converter = containerProperty.ItemConverter;
}
else if (containerContract != null && containerContract.ItemConverter != null)
{
converter = containerContract.ItemConverter;
}
else if (contract != null)
{
JsonConverter matchingConverter;
if (contract.Converter != null)
// class attribute converter
converter = contract.Converter;
else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
// passed in converters
converter = matchingConverter;
else if (contract.InternalConverter != null)
// internally specified converter
converter = contract.InternalConverter;
}
return converter;
}