Json.NET将序列化程序配置为重用对象实例以获得相等的令牌

时间:2016-03-10 09:45:25

标签: c# json json.net deserialization

我有两行发票。在这两行中,我选择了相同的产品项目。现在我想用Json.NET(以前的Newtonsoft.Json)反序列化它:

{
   "invoiceNumber":"SALES-001",
   "lines":[
      {
         "itemId":1,
         "lineDescription":"product with discount",
         "quantity":1,
         "price":1000,
         "item":{
            "id":1,
            "description":"product",
            "salesPrice":1200
         }
      },
      {
         "itemId":1,
         "lineDescription":"product",
         "quantity":1,
         "price":1200,
         "item":{
            "id":1,
            "description":"product",
            "salesPrice":1200
         }
      }
   ]
}

将其反序列化为C#对象时,我相信每个项目都会创建一个新实例,有点像:

new Item { Id = 1, Description = "product", SalesPrice = 1200 }

但我真正想要的是,在反序列化过程中,在第一行创建的item的对象实例将在第二行重用(通过对象比较?)。

阅读我找不到的文档。通过我看到的代码JsonSerializerSettings提供了ObjectCreationHandling.ReusePreserveReferencesHandling.Objects。只有这似乎没有达到预期的效果。所以我认为配置是不可能的。

任何建议都会很棒!

1 个答案:

答案 0 :(得分:0)

好的,所以对于Json.NET,你可以做到这一点。但必须更改JSON图以使其正常工作。

我无法找到描述此行为的标准。如果将JSON更改为:

,Json.NET似乎会重用对象实例
{
    "$id":1,
    "invoiceNumber":"SALES-001",
    "lines":[
        {
            "$id":2,
            "itemId":1,
            "lineDescription":"product with discount",
            "quantity":1,
            "price":1000,
            "item":{
                "$id":3,
                "id":1,
                "description":"product",
                "salesPrice":1200
            }
        },
        {
            "$id":4,
            "itemId":1,
            "lineDescription":"product",
            "quantity":1,
            "price":1200,
            "item":{
                "$ref":3
             }
        }
    ]
}

在这里,您可以看到每个对象都获得了唯一的"$id"分配。第一个item得到"$id": 3,图表中的第二个item引用此"$ref": 3

我找到了一个处理JavaScript对象转换的项目:https://bitbucket.org/smithkl42/jsonnetdecycle

来自项目的引用:

  

JsonNetDecycle

     

这是一个非常简单的TypeScript / JavaScript库,可以使用   重新建立Json.NET删除的对象引用。它的基础是   Douglas Crockford的cycle.js库,但使用的是非标准的   Json.NET使用的引用样式而不是IETF草案提案   为JSON references。在你问之前,是的,它可能会更好   如果Json.NET采用了IETF提出的标准。但我们中的一些人需要   在此之前完成工作可能会发生。

     

你使用它有点像这样:

var room = {
    "$id": "57",
    "Name": "_default",
    "User": {
        "$id": "58",
        "UserTag": "ken",
        "Sessions": [{
            "$id": "59",
            "SessionId": "0ca7474e-273c-4eb2-a0c1-1eba2f1a711c",
            "User": {
                "$ref": "58"
            },
            "Room": {
                "$ref": "57"
            }
        }],
    },

    "Sessions": [{
        "$ref": "59"
    }]
};
JsonNetDecycle.retrocycle(room);
alert(room.Sessions[0].User.UserTag);