【问题标题】:Deserializing abstract Queue<T> in Json [duplicate]在 Json 中反序列化抽象 Queue<T> [重复]
【发布时间】:2015-03-23 15:42:19
【问题描述】:

我有一个抽象类 KVP 的队列。我排队从 KVP 继承的 2 个不同的对象。当我序列化队列时一切正常,但由于无法构造 KVP,因此反序列化失败。

如果它是单个非通用对象,我可以将其反序列化为动态对象,但我不确定如何反序列化可以同时保存事件和 ID 的队列。

示例代码:

public virtual async Task<bool> LoadFromFile(string FileName, bool addToExistingQueue,bool DeleteFileAfterLoad = true)
        {
            try
            {
                IFile File = await PCLStorage.FileSystem.Current.LocalStorage.GetFileAsync(FileName);
                var serializedText = await File.ReadAllTextAsync();
                var mQueue = JsonConvert.DeserializeObject<Queue<T>>(serializedText,jss);
                if (!addToExistingQueue)
                {
                    _queue = new ConcurrentQueue<T>();
                }
                while (mQueue.Count > 0)
                {
                    _queue.Enqueue(mQueue.Dequeue());
                }




                if (DeleteFileAfterLoad)
                {
                    await File.DeleteAsync();
                }
                return true;

            }
            catch (Exception ex)
            {
                Debug.WriteLine("Could not load File. Exception Message: " + ex.Message);
                return false;
            }

        }
        public virtual async Task<bool> WriteToFile(string FileName)
        {
            try
            {
                Debug.WriteLine("Writing File: " + FileName);
                var File = await FileSystem.Current.LocalStorage.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting);
                var serializedText = JsonConvert.SerializeObject(_queue.ToList(),jss);
                await File.WriteAllTextAsync(serializedText);
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Could not write File with exception message: " + ex.Message);
                return false;
            }

        }

【问题讨论】:

  • 什么是 KVP?你是说键值对吗?
  • 您能否发布一些带有您的问题的示例 json 以便给我们一个更好的主意?
  • @Liam 是的,我创建的抽象类并不重要。
  • 我刚刚在另一篇文章中找到了 TypeNameHandling。 stackoverflow.com/questions/20038441/…

标签: c# generics serialization queue json.net


【解决方案1】:

你可以

  1. 启用TypeNameHandling(在序列化和反序列化中):

        var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
        var serializedText= JsonConvert.SerializeObject(mQueue, settings);
    

    后来

        var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
        var mQueue = JsonConvert.DeserializeObject<Queue<T>>(serializedText, settings);
    

    这会为您的多态类添加一个额外的"$type" 属性,如here 所述。

    在选择此解决方案之前,有关使用TypeNameHandling 可能存在的安全问题的讨论,请参阅TypeNameHandling caution in Newtonsoft JsonHow to configure Json.NET to create a vulnerable web API

  2. 编写一个自定义转换器,查看实际属性并选择要使用的派生类,如下所述:Deserializing polymorphic json classes without type information using json.net。这避免了额外的 "$type" 属性的需要。

【讨论】:

    【解决方案2】:

    如果您在 JSON.NET 序列化程序设置中使用以下设置,这应该可以工作:

    var settings = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto};
    

    这会将对象类型编码到 JSON 流中,这将有助于反序列化器在反序列化过程中确定要构造的特定对象类型。

    【讨论】:

      猜你喜欢
      • 2012-11-18
      • 2019-06-20
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      相关资源
      最近更新 更多