Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.net override method in DefaultContractResolver to deserialize private setters

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());

    }
}
like image 390
rakesh Avatar asked Aug 01 '14 10:08

rakesh


People also ask

Does Newtonsoft JSON serialize private fields?

JSON.NET can handle serializing and deserializing private fields, but you have to tell it to do so. In the past, you had to set the DefaultMembersSearchFlags property of the ContractResolver of your settings. But this property is now marked obsolete.

What does JsonConvert DeserializeObject do?

Deserializes the JSON to the specified . NET type. Deserializes the JSON to the specified . NET type using a collection of JsonConverter.

What is JsonProperty C#?

This sample uses JsonPropertyAttribute to change the names of properties when they are serialized to JSON. Types. public class Videogame { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("release_date")] public DateTime ReleaseDate { get; set; } }

Which of the following attribute should be used to indicate the property must not be serialized while using JSON serializer?

We still use [JsonIgnore] attribute, adding it to the property which we do not want to be serialized. Add an alternate private property setter to the class with the same type as the original property. Then set the value to the original property in the implementation.


3 Answers

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;
    }
like image 181
rakesh Avatar answered Oct 19 '22 10:10

rakesh


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;
    }
}
like image 31
Muris Avatar answered Oct 19 '22 10:10

Muris


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

like image 2
Daniel Avatar answered Oct 19 '22 10:10

Daniel