Herbstein Herbstein - 11 months ago 58
JSON Question

JSON.NET does not deserialize onto private properties

I'm trying to deserialize JSON from a REST service. I'm deserializing the JSON into a struct. The struct contains public properties. I want to hide the basic

objects, and use correct objects for each value. In doing this I hid the original properties, and wanted to find a way to populate them despite that. I found a relevant answer here on stackoverflow. The problem is that the private properties don't actually get assigned any value during deserialization.

I then tried to create my own
. I found the below code for the
CreateProperty(MemberInfo member, MemberSerialization memberSerialization)

var prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable)
var property = member as PropertyInfo;
if (property != null)
var hasPrivateSetter = property.GetSetMethod(true) != null;
prop.Writable = hasPrivateSetter;

return prop;

This still doesn't assign to completely private properties. I'm not sure how to proceed from here, since all the solutions I have been able to find use variations of these two solutions. How should I proceed?


I have created a small example that showcases my issue. https://gist.github.com/Herbstein/9ea14e2a4d95dd5aa4430384bfeeedf3

Answer Source

It isn't enough to handle private setters, you have to allow for the property itself being private:

internal class PrivateResolver : DefaultContractResolver {
    protected override IList<JsonProperty> CreateProperties(
        Type type, MemberSerialization memberSerialization
    ) {
        return type
            .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
            .Select(p => CreateProperty(p, memberSerialization))

    protected override JsonProperty CreateProperty(
        MemberInfo member, MemberSerialization memberSerialization
    ) {
        var prop = base.CreateProperty(member, memberSerialization);
        if (!prop.Writable && (member as PropertyInfo)?.GetSetMethod(true) != null) {
            prop.Writable = true;
        return prop;

I'd be remiss if I didn't also mention AutoMapper as a more general solution for problems like this. That requires you to declare more classes, but also keeps the types themselves simpler.