10

I have a class with properties that have private setters and i would like for those properties to be deSerialized using Json.Net. i know that i can use the [JsonProperty] attribute to do this bit i want to do this by implementing the DefaultContractResolver. Here is some example code i have been using but this dosent work.

static void Main(string[] args)
{
    var a = new a();
    a.s = "somestring";
    a.set();
    Console.WriteLine(JsonConvert.SerializeObject(a));
    var strrr = JsonConvert.SerializeObject(a);

    var strobj = JsonConvert.DeserializeObject<a>(strrr,new                        JsonSerializerSettings
    {
        ContractResolver = new PrivateSetterContractResolver()
    });
    Console.Read();
}

this is the class i want to serialize

public class a
{
    private int test;
    public int Test
    {
        get { return test; }
        private set { test = value; }
    }
    public string s { get; set; }

    public void set()
    {
        test = 33;
    }
}

this is the implementation of DefaultContractResolver

public class PrivateSetterContractResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        // whait do i do here ??? 

        //this dosent work
        return new List<MemberInfo>(objectType.GetProperties().ToList());

    }
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
rakesh
  • 301
  • 1
  • 3
  • 12

3 Answers3

9

Found the solution here . i was trying to override the wrong method. you need to override the CreateProperty method

protected override JsonProperty 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;
    }
rakesh
  • 301
  • 1
  • 3
  • 12
2

It is enough to tag private properties, or properties with private setter with JsonPropertyAttribute. Then they are automatically serialized as well. So no override is necessary.

So like class would look like:

public class a
{
    private int test;
    [JsonProperty]
    public int Test
    {
        get { return test; }
        private set { test = value; }
    }
    public string s { get; set; }

    [JsonProperty]
    public string anotherProperty { get; private set;}        

    public void set()
    {
        test = 33;
    }
}
Muris
  • 158
  • 8
2

As stated in the solution/answer here: Private setters in Json.Net

I've written a source distribution NuGet for this, that installs a single file with two custom contract resolvers:

  • PrivateSetterContractResolver
  • PrivateSetterCamelCasePropertyNamesContractResolver

Install the NuGet:

Install-Package JsonNet.PrivateSettersContractResolvers.Source

Then just use any of the resolvers:

var settings = new JsonSerializerSettings
{
    ContractResolver = new PrivateSetterContractResolver()
};

var model = JsonConvert.DeserializeObject<Model>(json, settings);

You can read about it here: http://danielwertheim.se/json-net-private-setters-nuget/

GitHub repo: https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers

Community
  • 1
  • 1
Daniel
  • 8,133
  • 5
  • 36
  • 51