Json反序列化受保护的属性[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Json反序列化受保护的属性[重复]相关的知识,希望对你有一定的参考价值。

我有一个类属性集,并在构造函数中修复,下面的示例是一个Guid.NewGuid() ..

理由是只允许类在创建时填充..所以它在构造函数中设置,并且仅标记为get; - 工作正常,直到我序列化/反序列化为Json。

似乎因为没有set;反序列化失败..并且构造函数介入并创建一个新的guid

我已经尝试了内部,私有和受保护的设置......但都会导致属性的重新生成,我能让它工作的唯一方法是将Id标记为{get;set;}

class Foo
{
    public Foo() => Id = Guid.NewGuid().ToString();
    public string Id { get; set; }
}

这意味着你可以简单地做:

var obj = new Foo();
obj.Id = "Any Old Rubbish";

有没有办法解决这个问题?

短样本:

class Program
{
    static void Main()
    {
        var obj = new Foo();
        Console.WriteLine(obj.Id);

        var serialize = JsonConvert.SerializeObject(obj);
        var deserialize = JsonConvert.DeserializeObject<Foo>(serialize);
        Console.WriteLine(deserialize.Id);

        Console.ReadLine();
    }
}

class Foo
{
    public Foo() => Id = Guid.NewGuid().ToString();

    public string Id { get; }
}

输出:

7868a298-f20d-4719-85ef-ba64c8658819
34fe422c-9555-4d17-ae1a-9fbf21af1b71
答案

下面的图像(它不是由我完成但是在this问题中找到)显示了JsonConvert.DeserializeObjectworks的算法。如您所见,几乎总是调用序列化类型的构造函数。这就是为什么你必须使用带参数的构造函数作为图像最左边的路径显示的原因。

JsonConvert.DeserializeObject algorithm

下面显示了使用带参数的构造函数对示例的修改。

class Program
{
  static void Main()
  {
    var obj = new Foo(Guid.NewGuid().ToString());
    Console.WriteLine(obj.Id);

    var serialize = JsonConvert.SerializeObject(obj);
    var deserialize = JsonConvert.DeserializeObject<Foo>(serialize);
    Console.WriteLine(deserialize.Id);

    Console.ReadLine();
  }
}

class Foo
{
  public Foo(String Id) => this.Id = Id;        
  public string Id { get; }
}

这将导致在序列化之前和之后具有相同的guid,而不需要使用public string Id { get; set;},因为您不想这样做。

以上是关于Json反序列化受保护的属性[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套对象中的属性反序列化 JSON [重复]

json_encode类时丢失私有属性和受保护属性处理方法

json.net中属性的自定义反序列化[重复]

从 JSON 反序列化重复字典

Json.net反序列化不反序列化所有属性

反序列化 JSON 会在表中创建另一个属性并且无法正确返回数据