在DefaultContractResolver中使用Json.net覆盖方法来反序列化私有setter

时间:2014-08-01 10:10:03

标签: c# json serialization get json.net

我有一个properties的课程,它有私人制定者,我希望使用Json.Net对这些属性进行deSerialized。我知道我可以使用[JsonProperty]属性来执行此操作,我希望通过实现DefaultContractResolver来实现此目的。 这是我一直在使用的一些示例代码,但这个代理工作。

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

这是我要序列化的类

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;
    }
}

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

    }
}

3 个答案:

答案 0 :(得分:7)

找到解决方案here 。我试图覆盖错误的方法。您需要覆盖CreateProperty方法

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;
    }

答案 1 :(得分:4)

用私有设置器JsonPropertyAttribute标记私有属性或属性就足够了。然后它们也会自动序列化。 所以不需要覆盖。

所以像课程一样:

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;
    }
}

答案 2 :(得分:2)

正如解决方案/答案中所述:Private setters in Json.Net

我为此编写了一个源代码分发NuGet,它安装了一个带有两个自定义合同解析器的文件:

  • PrivateSetterContractResolver
  • PrivateSetterCamelCasePropertyNamesContractResolver

安装NuGet:

Install-Package JsonNet.PrivateSettersContractResolvers.Source

然后只使用任何一个解析器:

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

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

您可以在此处阅读:http://danielwertheim.se/json-net-private-setters-nuget/

GitHub回购:https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers