• <bdo id='xa6B0'></bdo><ul id='xa6B0'></ul>
  1. <small id='xa6B0'></small><noframes id='xa6B0'>

    1. <legend id='xa6B0'><style id='xa6B0'><dir id='xa6B0'><q id='xa6B0'></q></dir></style></legend>

      <tfoot id='xa6B0'></tfoot>
      <i id='xa6B0'><tr id='xa6B0'><dt id='xa6B0'><q id='xa6B0'><span id='xa6B0'><b id='xa6B0'><form id='xa6B0'><ins id='xa6B0'></ins><ul id='xa6B0'></ul><sub id='xa6B0'></sub></form><legend id='xa6B0'></legend><bdo id='xa6B0'><pre id='xa6B0'><center id='xa6B0'></center></pre></bdo></b><th id='xa6B0'></th></span></q></dt></tr></i><div id='xa6B0'><tfoot id='xa6B0'></tfoot><dl id='xa6B0'><fieldset id='xa6B0'></fieldset></dl></div>

      如何反序列化 Newtonsoft Json.NET 对单独实例的引用

      How to deserialize Newtonsoft Json.NET references to separate, individual instances(如何反序列化 Newtonsoft Json.NET 对单独实例的引用)
      • <small id='LBwY6'></small><noframes id='LBwY6'>

        <legend id='LBwY6'><style id='LBwY6'><dir id='LBwY6'><q id='LBwY6'></q></dir></style></legend>
      • <tfoot id='LBwY6'></tfoot>

          <bdo id='LBwY6'></bdo><ul id='LBwY6'></ul>
          • <i id='LBwY6'><tr id='LBwY6'><dt id='LBwY6'><q id='LBwY6'><span id='LBwY6'><b id='LBwY6'><form id='LBwY6'><ins id='LBwY6'></ins><ul id='LBwY6'></ul><sub id='LBwY6'></sub></form><legend id='LBwY6'></legend><bdo id='LBwY6'><pre id='LBwY6'><center id='LBwY6'></center></pre></bdo></b><th id='LBwY6'></th></span></q></dt></tr></i><div id='LBwY6'><tfoot id='LBwY6'></tfoot><dl id='LBwY6'><fieldset id='LBwY6'></fieldset></dl></div>
              <tbody id='LBwY6'></tbody>

                本文介绍了如何反序列化 Newtonsoft Json.NET 对单独实例的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                限时送ChatGPT账号..

                我有一段如下所示的 JSON:

                I have a piece of JSON that looks like this:

                [
                  {
                    "$id": "1",
                    "Name": "James",
                    "BirthDate": "1983-03-08T00:00Z",
                    "LastModified": "2012-03-21T05:40Z"
                  },
                  {
                    "$ref": "1"
                  }
                ]
                

                从 $ref 可以看出,这个 JSON 数组包含两次相同的 Person (James).第二次是对第一次的引用.

                As you can tell by the $ref, this JSON array contains the same Person (James), twice. The second time is a reference to the first.

                我想知道是否有办法将这个 JSON 反序列化成一个包含詹姆斯人的两个副本的对象.

                I am wondering if there is a way to deserialize this JSON into an object that contains two copies of the James person.

                目前,我正在使用这个:

                Currently, I'm using this:

                var jsonSerializerSettings = new JsonSerializerSettings()
                {
                     PreserveReferencesHandling = PreserveReferencesHandling.None,
                     ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                };
                
                var deserializedPersons = JsonConvert.DeserializeObject<List<Person>>(json, jsonSerializerSettings);
                

                但这只是给了我一个具有相同 Person 实例的数组,两次:

                But this just gives me an array with the same instance of the Person, twice:

                object.ReferenceEquals(deserializedPersons[0], deserializedPersons[1]) // Evaluates to true
                

                我找到了一个我不满意的解决方法,它只是反序列化 JSON 字符串,然后使用上面的 jsonSerializerSettings 对其进行序列化,这将复制 JSON 中的人,然后再次对其进行反序列化.这会导致我们正在使用的大型对象严重减速.

                I've found a workaround I am unhappy with which is simply deserializing the JSON string, then serializing it using the jsonSerializerSettings above, which will duplicate the person in the JSON, then deserializing it again. This is causing major slowdowns for the large objects we are using.

                注意:我知道我可以更改从中检索此 JSON 的 API 以复制数据,但在发送响应 JSON 时保留引用可以节省大量空间电线.

                Note: I know I could change the API that I retrieve this JSON from to duplicate the data, but preserving the references saves substantial space when sending the response JSON over the wire.

                推荐答案

                你可以使用 自定义参考解析器.例如,假设 Name 是您的对象的主键",这应该可以工作.当然,您可能想让它更通用.

                You could use a custom reference resolver. For example, assuming Name is the "primary key" for your objects, this should work. Of course, you may want to make it more generic.

                public class PersonReferenceResolver : IReferenceResolver
                {
                    private readonly IDictionary<string, Person> _objects = 
                        new Dictionary<string, Person>();
                
                    public object ResolveReference(object context, string reference)
                    {
                        Person p;
                        if (_objects.TryGetValue(reference, out p))
                        {
                            //This is the "clever" bit. Instead of returning the found object
                            //we just return a copy of it.
                            //May be better to clone your class here...
                            return new Person
                            {
                                Name = p.Name,
                                BirthDate = p.BirthDate,
                                LastModified = p.LastModified
                            };
                        }
                
                        return null;
                    }
                
                    public string GetReference(object context, object value)
                    {
                        Person p = (Person)value;
                        _objects[p.Name] = p;
                
                        return p.Name;
                    }
                
                    public bool IsReferenced(object context, object value)
                    {
                        Person p = (Person)value;
                
                        return _objects.ContainsKey(p.Name);
                    }
                
                    public void AddReference(object context, string reference, object value)
                    {
                        _objects[reference] = (Person)value;
                    }
                }
                

                现在你像这样反序列化:

                Now you deserialise like this:

                var jsonSerializerSettings = new JsonSerializerSettings()
                {
                    ReferenceResolver = new PersonReferenceResolver()
                };
                
                var deserializedPersons = JsonConvert.DeserializeObject<List<Person>>(
                    json, jsonSerializerSettings);
                

                <小时>

                我很无聊,所以我做了一个通用版本:


                I was bored so I made a generic version:

                public class GenericResolver<TEntity> : IReferenceResolver
                    where TEntity : ICloneable, new()
                {
                    private readonly IDictionary<string, TEntity> _objects = new Dictionary<string, TEntity>();
                    private readonly Func<TEntity, string> _keyReader;
                
                    public GenericResolver(Func<TEntity, string> keyReader)
                    {
                        _keyReader = keyReader;
                    }
                
                    public object ResolveReference(object context, string reference)
                    {
                        TEntity o;
                        if (_objects.TryGetValue(reference, out o))
                        {
                            return o.Clone();
                        }
                
                        return null;
                    }
                
                    public string GetReference(object context, object value)
                    {
                        var o = (TEntity)value;
                        var key = _keyReader(o);
                        _objects[key] = o;
                
                        return key;
                    }
                
                    public bool IsReferenced(object context, object value)
                    {
                        var o = (TEntity)value;
                        return _objects.ContainsKey(_keyReader(o));
                    }
                
                    public void AddReference(object context, string reference, object value)
                    {
                        if(value is TEntity)
                            _objects[reference] = (TEntity)value;
                    }
                }
                

                稍微新的用法:

                var jsonSerializerSettings = new JsonSerializerSettings()
                {
                    //Now we need to specify the type and how to get the object's key
                    ReferenceResolver = new GenericResolver<Person>(p => p.Name)
                };
                
                var deserializedPersons = JsonConvert.DeserializeObject<List<Person>>(
                    json, jsonSerializerSettings);
                

                这篇关于如何反序列化 Newtonsoft Json.NET 对单独实例的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                Force JsonConvert.SerializeXmlNode to serialize node value as an Integer or a Boolean(强制 JsonConvert.SerializeXmlNode 将节点值序列化为整数或布尔值)
                Using JSON to Serialize/Deserialize TimeSpan(使用 JSON 序列化/反序列化 TimeSpan)
                Could not determine JSON object type for type quot;Classquot;(无法确定类型“Class的 JSON 对象类型.)
                How to deserialize a JSONP response (preferably with JsonTextReader and not a string)?(如何反序列化 JSONP 响应(最好使用 JsonTextReader 而不是字符串)?)
                how to de-serialize JSON data in which Timestamp it-self contains fields?(如何反序列化时间戳本身包含字段的JSON数据?)
                JSON.Net custom contract serialization and Collections(JSON.Net 自定义合约序列化和集合)

                • <tfoot id='F4DSC'></tfoot>
                    • <bdo id='F4DSC'></bdo><ul id='F4DSC'></ul>
                      <legend id='F4DSC'><style id='F4DSC'><dir id='F4DSC'><q id='F4DSC'></q></dir></style></legend>

                            <tbody id='F4DSC'></tbody>

                          <i id='F4DSC'><tr id='F4DSC'><dt id='F4DSC'><q id='F4DSC'><span id='F4DSC'><b id='F4DSC'><form id='F4DSC'><ins id='F4DSC'></ins><ul id='F4DSC'></ul><sub id='F4DSC'></sub></form><legend id='F4DSC'></legend><bdo id='F4DSC'><pre id='F4DSC'><center id='F4DSC'></center></pre></bdo></b><th id='F4DSC'></th></span></q></dt></tr></i><div id='F4DSC'><tfoot id='F4DSC'></tfoot><dl id='F4DSC'><fieldset id='F4DSC'></fieldset></dl></div>

                          <small id='F4DSC'></small><noframes id='F4DSC'>