从 json 反序列化受保护的构造对象

发布于 2024-11-04 10:32:10 字数 1072 浏览 0 评论 0原文

我正在使用牛顿的 json.net 序列化器。将 json 反序列化为 'TheFox' 时;它进入受保护的构造函数并获取默认属性值。但不是 json 字符串中的属性值。我可以在不使用 dto 或任何其他映射器框架的情况下解决这个问题吗?

class TheFox
    {

    string _Id;
    string _Name;

    protected TheFox()
    {
        _Id = "Default Id";
        _Name = "Default Name";
    }

    public TheFox(string id, string name) : this()
    {
        _Name = name;
        _Id = id;
    }

    public string Id
    {
        get { return _Id; }
    }

    public string Name
    {
        get { return _Name; }
    }
}

这就是测试:

        var fox = new TheFox("FoxId", "FoxTail");
        var json = JsonConvert.SerializeObject(fox);
        Console.WriteLine(json);

        var settings = new JsonSerializerSettings ()
        {
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
        };

        var returned = JsonConvert.DeserializeObject<TheFox> (json, settings);

        Assert.IsTrue (returned.Id != "Default Id");
        Assert.IsTrue (returned.Name != "Default Name");

I'm using newton's json.net serializer. When deserializing the json to 'TheFox'; it enters to the protected ctor and gets the default property values. But not the property values in the json string. Can i solve this problem without using dto or any other mapper framework?

class TheFox
    {

    string _Id;
    string _Name;

    protected TheFox()
    {
        _Id = "Default Id";
        _Name = "Default Name";
    }

    public TheFox(string id, string name) : this()
    {
        _Name = name;
        _Id = id;
    }

    public string Id
    {
        get { return _Id; }
    }

    public string Name
    {
        get { return _Name; }
    }
}

That's the test:

        var fox = new TheFox("FoxId", "FoxTail");
        var json = JsonConvert.SerializeObject(fox);
        Console.WriteLine(json);

        var settings = new JsonSerializerSettings ()
        {
            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
        };

        var returned = JsonConvert.DeserializeObject<TheFox> (json, settings);

        Assert.IsTrue (returned.Id != "Default Id");
        Assert.IsTrue (returned.Name != "Default Name");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不疑不惑不回忆 2024-11-11 10:32:10

查了一下json.net的源码,暂时没有办法。因为如果给定的属性是只读的,它会跳过设置值阶段。可能需要内部现场填充器功能。

private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
    {
      // bla.. bla.. bla..
      if (!property.Writable && !useExistingValue)
      {
        reader.Skip();
        return;
      }

该方法是一个糟糕的方法,它需要一个实例化的对象来填充,但它有效。

var a = new TheFox("x", "y");
var json = JsonConvert.SerializeObject(a);
Console.WriteLine(json);

var returned = JsonConvert.DeserializeAnonymousType(json, new TheFox("q", "a")); 

Assert.That(a.Id, Is.EqualTo(returned.Id));
Assert.That(a.Name, Is.EqualTo(returned.Name));

Checked the source of in json.net and there's no way for now. Because if the given property is readonly it skips the setting the value stage. may be needs an internal field populator feature.

private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
    {
      // bla.. bla.. bla..
      if (!property.Writable && !useExistingValue)
      {
        reader.Skip();
        return;
      }

That method is a bad one, it needs an instantiated object to fill but it works.

var a = new TheFox("x", "y");
var json = JsonConvert.SerializeObject(a);
Console.WriteLine(json);

var returned = JsonConvert.DeserializeAnonymousType(json, new TheFox("q", "a")); 

Assert.That(a.Id, Is.EqualTo(returned.Id));
Assert.That(a.Name, Is.EqualTo(returned.Name));
紫罗兰の梦幻 2024-11-11 10:32:10
    class TheFox
    {
      string _Id;
      string _Name;

      protected TheFox() : this("Default Id", "Default Name")

      public TheFox(string id, string name)
      {
        _Name = name;
        _Id = id;
      }

      public string Id
      {
        get { return _Id; }
      }

      public string Name
      {
        get { return _Name; }
      }
}

这应该允许相同的用法,但提供与牛顿的可比性。

    class TheFox
    {
      string _Id;
      string _Name;

      protected TheFox() : this("Default Id", "Default Name")

      public TheFox(string id, string name)
      {
        _Name = name;
        _Id = id;
      }

      public string Id
      {
        get { return _Id; }
      }

      public string Name
      {
        get { return _Name; }
      }
}

This should allow for the same usage but offers comparability with newton.

丢了幸福的猪 2024-11-11 10:32:10

您的课程不适合客户端操作。您需要对类使用 DataContractAttribute,对要序列化的成员使用 DataMemberAttribute 属性。

Your class is not appropriate for client side operation. You need to use DataContractAttribute to the class and DataMemberAttribute attribute to the members you want to serialize.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文