【问题标题】:Deserializing json to C# list with existing items使用现有项目将 json 反序列化为 C# 列表
【发布时间】:2015-06-25 04:47:32
【问题描述】:

给定以下类:

class Report {

    public Report() {
        this.Fields=new List<Field>();
    }

    [JsonProperty("fields")]
    public IList<Field> Fields { get; private set; }
}

class Field {

    [JsonProperty("identifier")]
    public Guid Identfier { get;set; }

    [JsonProperty("name")]
    public string Name { get;set; }
}

并设置以下测试方法:

var report = new Report();
report.Fields.Add(new Field { Identifier = new Guid("26a94eab-3d50-4330-8203-e7750abaa060"), Name = "Field 1" });
report.Fields.Add(new Field { Identifier = new Guid("852107db-b5d1-4344-9f71-7bd90b96fec0"), Name = "Field 2" });

var json = "{\"fields\":[{\"identifier\":\"852107db-b5d1-4344-9f71-7bd90b96fec0\",\"name\":\"name changed\"},{\"identifier\":\"ac424aff-22b5-4bf3-8232-031eb060f7c2\",\"name\":\"new field\"}]}";

JsonConvert.PopulateObject(json, report);

Assert.IsTrue(report.Fields.Count == 2, "The number of fields was incorrect.");

我如何让 JSON.Net 知道标识符为“852107db-b5d1-4344-9f71-7bd90b96fec0”的字段应该应用于具有相同标识符的现有字段?

另外,是否有可能让 JSON.Net 删除给定 JSON 数组中不存在的项目,(特别是标识符为“26a94eab-3d50-4330-8203-e7750abaa060”的字段应该被删除,因为它不存在于给定的 json 数组中。

如果有办法手动编码或覆盖 JSON 分析列表的方式,那会更好,因为我可以编写代码说“这是您需要的项目”或“使用这个新创建的项目”或只是“不要对这个项目做任何事情,因为我已经删除了它”。请问有人知道我可以这样做吗?

【问题讨论】:

  • 你想达到什么目的? json 字符串来自哪里?您能简单地使用JsonConvert.SerializeObject&lt;T&gt;JsonConvert.DeserializeObject 并比较其中的元素吗?
  • 我目前正在这样做,但我有很多很多这样的对象和子对象,我现在都是手动完成的,如果有一个自动化的会更好我只能说“这是此项目的密钥,匹配并更新它,或者丢失它,或者如果它不存在则创建”。也许我要问的是 JSON 以某种方式提供 CRUD 以列出元素。如果我必须对其进行编码,我可以接受,但是编码一次比编码我剩下要做的每个对象更好更快。
  • 如果您将对象反序列化为 List,则 IEnumerable 扩展方法提供了一种非常方便的方法。也会更具可读性,恕我直言。
  • 这是这个问题的副本吗? stackoverflow.com/questions/20270266/…

标签: c# json json.net


【解决方案1】:

您可以使用选项ObjectCreationHandling = ObjectCreationHandling.Replace

您可以使用序列化程序设置为整个数据模型执行此操作,如Json.Net PopulateObject Appending list rather than setting value 所示:

    var serializerSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
    JsonConvert.PopulateObject(json, report, serializerSettings);

或者,如果您不想普遍这样做,可以在您已经使用的 JsonProperty 属性上设置选项:

class Report
{
    public Report()
    {
        this.Fields = new List<Field>();
    }

    [JsonProperty("fields", ObjectCreationHandling = ObjectCreationHandling.Replace)]
    public IList<Field> Fields { get; private set; }
}

【讨论】:

  • 但是当我有一个 guid 说值“x”(为简单起见)将其 json 值应用于具有 guid“x”的对象时,这并没有真正起作用。我需要说替换/更新的关键是标识符字段。
  • @Anupheaus - 我已经很久没有看到这个了。您希望删除旧列表中在新列表中没有对应条目的条目,并替换旧列表中在新列表中有对应条目的条目。这是否意味着旧列表中的所有条目都将被新列表替换?如果没有,您能否进行快速的单元测试来显示问题所在?我的代码通过了您问题中的测试。
猜你喜欢
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2022-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多