NewtonSoft JsonConverter - Access other properties
There is no way to access the parent object from a JsonConverter. For example if there was a need to alter the output of the converter that is dependent on containing object that is being serialized. In my specific use case, I need to format the JSON output for a property as a currency string, dependent on the
Culture that is stored within the containing object.
eg.
public class Contract {
[JsonIgnore]
public CultureInfo Culture {get; set;}
[JsonConverter(typeof(CurrencyConverter))]
public decimal Cost {get;set;}
// Lots of additional properties with serialization controlled by attributes.
}
With an array of contracts I'd get the following JSON [{ Cost : "£5000.00"}, { Cost : "$8000.00"}, { Cost : "€599.00"}]
Expose the JsonSerializeWriter's _serializerStack as a ReadOnlyCollection as a public property on the serializer object passed to WriteJson.
If the output of the converter depends on the containing type, why not have the containing type be what is converted?
@JonHanna Because that means you need to handle the conversion of all the properties in the containing object rather that relying on the default behaviour using properties.
Also if you had a Contract
with many Vendor
s each with many Asset
s and the Asset
had a cost field that needed the output formatted depending on the Contract Culture you would have to write a converter for the Contract
that then serialized all the child properties. That creates a lot of extra code for the converter where a simple converter could walk the serialization tree to find that culture and format the output.
Your DTO objects would be relatively clean with attributes defining their behaviour and your converter also would be relatively simple without the need to map all the extra properties.
I've got it working by using reflection to call GetInternalSerializer()
on the passed JsonSerializer
and then retrieve the private _serializerStack
field. All it would need is for JsonSerializerInternalWriter
to expose the "_serializerStack" field as a property that the JsonSerializer
could also expose. My suggestion is to expose it as a read only collection to protect the internals.
I'd like to bump this, as it seems reflecting into the serializer is still the only way to get to the serialization stack.
Or is there another way by now?
Most helpful comment
@JonHanna Because that means you need to handle the conversion of all the properties in the containing object rather that relying on the default behaviour using properties.
Also if you had a
Contract
with manyVendor
s each with manyAsset
s and theAsset
had a cost field that needed the output formatted depending on the Contract Culture you would have to write a converter for theContract
that then serialized all the child properties. That creates a lot of extra code for the converter where a simple converter could walk the serialization tree to find that culture and format the output.Your DTO objects would be relatively clean with attributes defining their behaviour and your converter also would be relatively simple without the need to map all the extra properties.
I've got it working by using reflection to call
GetInternalSerializer()
on the passedJsonSerializer
and then retrieve the private_serializerStack
field. All it would need is forJsonSerializerInternalWriter
to expose the "_serializerStack" field as a property that theJsonSerializer
could also expose. My suggestion is to expose it as a read only collection to protect the internals.