使用JSON反序列化对象.NET,但将一些属性放入类的成员中

本文关键字:属性 成员 对象 反序列化 JSON NET 使用 | 更新日期: 2023-09-27 17:49:44

我正在编写一组数据结构,用于使用JSON.NET摄取第三方JSON(不写入)。

我有一个案例,将一些顶级JSON元素读取到被反序列化的对象的成员对象中。

我的JSON:

{
    "Id":1
    "Checksum":42
    "Name":"adam",
    "Hair":true
}

我理想的对象结构:

public class EntityHeader
{
    int Id { get; set; }
    int Checksum { get; set; }
}
public class Entity
{
    [HeroicJsonAttribute( "Id", "Checksum" )]
    public EntityHeader Header { get; set; }
    public string Name { get; set; }
    public bool Hair { get; set; }
}

是否有一个简单的方法来实现这一点?我将有许多类型需要这个,我讨厌为每个类型写一个JsonConverter。

这个问题以前也有人问过,但是公认的答案并没有解决这个问题。

谢谢!

使用JSON反序列化对象.NET,但将一些属性放入类的成员中

另一种方法是使用Entity类中的EntityHeader字段作为私有属性的后备存储,这些私有属性可以反序列化为:

public class EntityHeader
{
    int Id { get; set; }
    int Checksum { get; set; }
}
public class Entity
{
    private EntityHeader m_Header = new EntityHeader();
    public EntityHeader Header { get { return m_Header; } }
    [JsonProperty]
    private int Id { set { m_Header.Id = value; } }
    [JsonProperty]
    private int Checksum { set { m_Header.Checksum = value; } }
    public string Name { get; set; }
    public bool Hair { get; set; }
}

因此,JSON中的所有属性都可以直接读取到Entity对象中,但是Entity对象的消费者可以访问一个"很好地封装"的EntityHeader属性。

我还没有测试过这个,它甚至可能是笨拙的,但它在技术上对我有用(OP)。我仍然对其他答案感兴趣!

根据您的示例,您可以;使用适配器模式:

public class EntityJson
{
  int Id { get; set; }
  int Checksum { get; set; }
  public string Name { get; set; }
  public bool Hair { get; set; }
}
// quick/poor example
public class EntityAdapter : IEntity
{
  public EntityAdapter(EntityJson model)
  {
    Header = new Header(); // and populate this objects fields
    Name = model.Name; // populate other properties
  }
  public EntityHeader Header { get; set; }
  public string Name { get; set; }
  public bool Hair { get; set; }
}

或者滥用json.net忽略不可用属性的事实:

var entity = JsonConvert.Deserialze<Entity>();
var header = JsonConvert.Deserialize<EntityHeader>();
entity.Header = header;

我将继续发布这个答案,这个答案对于评论来说有点太长了,所以请把它当作一个扩展的评论,而不是实际尝试回答你的具体问题。当然,你最了解你的需求,所以这只是我经过深思熟虑的意见:)

考虑到这一点,我的建议是:

不要这样做。

  • 我会创建一个简单的DTO类,它与接收到的JSON具有1-1关系;我把所有的验证属性放在那个类的属性上。

  • 一旦我把JSON反序列化成这个简单的DTO,我就会使用某种映射层(滚你自己的或使用Automapper等)将这个DTO映射成一个更有意义的结构,如你的Entity类。

  • 我这样做的原因是因为除非你的Entity类本身只是一个简单的DTO(在这种情况下,它应该尽可能简单,理想情况下不是一个复合),你是混合OOP和关注与数据映射的关注;虽然这本身并不是一件坏事,但它只会增加代码的复杂性。

  • 考虑例如,如果您传入的JSON最终具有30或40个属性,并且您设法找出一种方法(可能从其他答案中适应一些不错的技术)将其映射到Entity类。但是,当出现问题时,将更容易推理,从而更容易调试,这是一个你可以更好地控制的过程;它也将更容易做出特殊的调整,以适应奇怪的边缘情况,其中序列化程序的行为不能帮助你

  • 虽然编写和维护这些dto需要一些工作,但是并不多——Webtools已经为你做了

参考:在边界处,应用程序不是面向对象的