Json反序列化受保护的财产

时间:2018-02-28 12:18:04

标签: c# json.net

我有一个类属性集,并在构造函数中修复,下面的例子是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

1 个答案:

答案 0 :(得分:2)

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

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;},因为您不想这样做。