【问题标题】:Serialize a Dictionary<string, object> that contains a List<string>?序列化包含 List<string> 的 Dictionary<string, object>?
【发布时间】:2013-01-16 01:03:51
【问题描述】:

我找到了一个工作得很好的可序列化字典:http://www.jankowskimichal.pl/en/2010/10/serializabledictionary/

但只要字典中的一个对象只是一个字符串列表,我就会遇到异常。 .NET 告诉我它不能序列化它:

Serialize 'C:\bin\Debug\Settings\Default.xml' : System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] may not be used in this context.
   at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObject.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObject.Write2_anyType(Object o)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
   at ShadowBot.Classes.SerializableDictionary`2.WriteXml(XmlWriter writer) in c:\Classes\SerializableDictionary.cs:line 114
   at System.Xml.Serialization.XmlSerializationWriter.WriteSerializable(IXmlSerializable serializable, String name, String ns, Boolean isNullable, Boolean wrapped)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterShadowSettings.Write2_ShadowSettings(String n, String ns, ShadowSettings o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterShadowSettings.Write3_ShadowSettings(Object o)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o, XmlSerializerNamespaces namespaces)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o)
   at Classes.XmlSerializer.Serialize(String Path, Object Object) in c:\Classes\XmlSerializer.cs:line 29

这甚至可能吗?我想要这种能力,只是假设你可以嵌套这样的对象。如果这是不可能的,有没有办法我可以将字典写入磁盘(不必是 XML)然后重新加载它而无需为此编写自定义包装器?我最初是一名 mac 开发人员,这种类型的序列化非常简单,所以我可能在 .NET 上遗漏了一些东西。

编辑:在尝试 odyss 示例时,我得到:

System.Runtime.Serialization.SerializationException: Type 'System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

【问题讨论】:

    标签: c# serialization xml-serialization invalidoperationexception


    【解决方案1】:

    我在序列化通用列表时遇到了类似的问题。尝试在序列化之前将列表更改为字符串数组string[],然后在反序列化后返回List&lt;string&gt;。这很容易做到,可能会解决您的问题:

    //List<string> to string[]
    string[] sArray = sList.ToArray();
    
    //string[] to List<string>
    List<string> sList = sArray.ToList();
    

    【讨论】:

      【解决方案2】:

      作为替代方案,System.Runtime.Serialization.DataContractSerializer 可能会让您的运气更好。示例:

      Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
      dict.Add("test", new List<string>() { "t", "b" });
      
      StringBuilder xmlString = new StringBuilder();
      using (XmlWriter writer = XmlWriter.Create(xmlString))
      {
          DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, List<string>>));
          serializer.WriteObject(writer, dict);
      }
      

      这会生成:

      <?xml version="1.0" encoding="utf-16"?><ArrayOfKeyValueOfstringArrayOfstringty7Ep6D1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><KeyValueOfstringArrayOfstringty7Ep6D1><Key>test</Key><Value><string>t</string><string>b</string></Value></KeyValueOfstringArrayOfstringty7Ep6D1></ArrayOfKeyValueOfstringArrayOfstringty7Ep6D1>
      

      【讨论】:

      • 你是怎么得到这个字符串的?
      • @Geesu 你的意思是,你如何反序列化它?
      • 没有,你是怎么粘贴它生成的?我正在尝试像这样打印到控制台:pastebin.com/3W7BZEtD 长度始终为 0
      • xmlString.ToString(),在using-clause 之外执行或调用writer.Flush() 以确保写入器在读出字符串之前刷新。
      • 是的,我是在里面做的,这就是问题所在。奇怪的是它适用于你的例子,但我的字典包含我得到的数据:另一个例外(见上面的编辑)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      相关资源
      最近更新 更多