【问题标题】:Make serialized JSON from C# null class instance return empty array使 C# 空类实例的序列化 JSON 返回空数组
【发布时间】:2015-08-20 19:24:00
【问题描述】:

给定以下简单的类:

public class Person
{
  public int id { get; set; }
  public List<Order> orders { get; set; }
}

当orders 属性为null,并且一旦Person 实例使用下面的JSON.NET 序列化:

var json = JsonConvert.SerializeObject(myPerson);

当orders = null:

{
 "id": 1,
 "orders": []
}

然而,正在发生的事情是 orders 属性被返回所有空值,如下所示:

{
 "id": 1,
 "orders": [
    {
      "id": null,
      "total":null,
      "orderDate":null,
      "itemQuantity":null
    }
  ]
}

如果null,我不能返回该集合,而是它需要显示为基本上是一个空数组,例如:"orders": []"

我试过了:

myPerson.orders = null;

但是,这仍然会产生以所有空值显示的完整对象集合。

我如何干预这个对象的序列化或操作,以便我可以让它作为一个空数组物理返回,而不是一个扩展的空字段集合?

编辑:部分问题是通过 cmets 回答的。返回的完整对象实例是由于 LINQ 查询返回的结果集实例化了默认实例 OF orders。然而,问题的主要部分仍然是让它返回 "orders":[] 和 not "orders":null

【问题讨论】:

  • 在代码中的某处分配默认的Order 并将其添加到列表中——可能在某些转换器或默认构造函数中。 Person 的默认构造函数是什么样的?
  • @dbc - 是的,这正是我现在要搜索的内容。 Person 的构造函数没有定义,它只是一个默认的空构造函数。正如你所说,我认为正在添加一个默认实例。无论如何,即使我找到它,我认为 null 将作为整个属性返回,我仍然需要 []
  • JsonConvert.SerializeObject(new Person() { id = 1, orders = null }) 给我{"id":1,"orders":null}。
  • @poke @dbc - 好的,问题的前半部分已回答。显然,为了简洁起见,我不得不省略一些问题的细节。我的代码在获取 LINQ 查询的结果时无意中添加了一个默认实例。所以现在我有"orders":null 但是,我仍然需要让它成为"orders":[] 我应该在序列化后强力查找/替换,还是有序列化程序设置/属性可以做到这一点?
  • 如果你使用person.orders = new List&lt;Order&gt;(),那么它应该是一个空数组而不是null。

标签: c# json asp.net-web-api json.net


【解决方案1】:
"orders": [
  {
    "id": null,
    "total":null,
    "orderDate":null,
    "itemQuantity":null
  }
]

您在上面看到的输出不能由人员的空 orders 属性引起。 JSON 数组确实有一个项目,因此订单列表中也需要有一个项目。它恰好具有所有属性的默认值,这就是为什么每个键都有一个null。

因此,如果您知道该空 Order 对象是在哪里创建并添加到列表中的,您就可以摆脱该输出。

至于序列化一个空列表,您有两个选择:您可以将其序列化为null,方法是直接将属性设置为null (person.orders = null)。或者,您可以通过为属性分配一个空列表 (person.orders = new List&lt;Order&gt;()) 将其序列化为一个空数组 []。

即使属性为null,您也可以操作序列化程序以始终创建一个空数组。示例见this answer。

【讨论】:

  • 很高兴我能帮上忙 :)
【解决方案2】:

你可以在类构造函数中初始化集合,然后你会得到你想要的输出:

public class Person
{
    public Person()
    {
        orders = new List<Order>();
    }

    public int id { get; set; }
    public List<Order> orders { get; set; }
}

此外,您可以为您的属性个性化 getter,但我个人不推荐这样做,因为如果出现错误很难找到它。

public class Person
{       
    public int id { get; set; }

    private List<Order> _orders;

    public List<Order> orders
    {
        get
        {
            if (_orders == null)
            {
                _orders = new List<Order>();
            }

            return _orders;
        }
        set { _orders = value; }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多