列表<string>未正确反序列化

时间:2015-11-13 11:29:59

标签: c# xml serialization

我有一个自定义Option类来保存对象,还有一些额外的参数(name,info ...)。我尝试序列化Option列表以保存设置。所有值类型和自定义可序列化类似乎都可以正常工作,但List没有正确反序列化。我得到的只是一个System.Xml.XmlNode而不是List。该节点包含列表中的值,它们不在列表中。

以下是Option类的相关部分:

#region DefaultValue

    private object _defaultObject = null;

   [SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Binary)]
    public object DefaultValue
    {
        get { return _defaultObject; }
        set
        {
            _defaultObject = value;
            NotifyPropertyChanged("DefaultValue");
        }
    }

    #endregion

    #region Value

    private object _object = null;

   [SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Binary)]
    public object Value
    {
        get { return _object; }
        set
        {
            if (DefaultValue == null)
            {
                DefaultValue = value;
                _object = value;
                NotifyPropertyChanged("Value");
            }
            else if (DefaultValue.GetType().IsAssignableFrom(value.GetType()))
            {
                _object = value;
                NotifyPropertyChanged("Value");
            }
        }
    }

以下是我如何将列表添加到列表中(第二个用于比较,并且在没有第一个的情况下正常工作):

Add(new Option() { Name = "ModuleFolders", DisplayName = "Module folders", Value = new List<String>() { ".\\Modules", "..\\Modules" }, Group = "Session", Info = "This is the list of folders containing all of the modules", ShortInfo = "Paths to the module folders"});
        Add(new Option() { Name = "ModulePattern", DisplayName = "Module pattern", Value = "GAME.Modules.*.dll", Group = "Session", Info = "This is the pattern used to find module assemblies by file name", ShortInfo = "Pattern for module names", IsReadOnly = true});

最后,这是生成的xml:

<?xml version="1.0"?>
<ArrayOfOption xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Option>
    <DefaultValue xsi:type="ArrayOfString">
      <string>.\Modules</string>
      <string>..\Modules</string>
    </DefaultValue>
    <Value xsi:type="ArrayOfString">
      <string>.\Modules</string>
      <string>..\Modules</string>
    </Value>
    <Name>ModuleFolders</Name>
    <DisplayName>Module folders</DisplayName>
    <ShortInfo>Paths to the module folders</ShortInfo>
    <Info>This is the list of folders containing all of the modules</Info>
    <Group>Session</Group>
    <IsReadOnly>false</IsReadOnly>
  </Option>
  <Option>
    <DefaultValue xsi:type="xsd:string">GAME.Modules.*.dll</DefaultValue>
    <Value xsi:type="xsd:string">GAME.Modules.*.dll</Value>
    <Name>ModulePattern</Name>
    <DisplayName>Module pattern</DisplayName>
    <ShortInfo>Pattern for module names</ShortInfo>
    <Info>This is the pattern used to find module assemblies by file name</Info>
    <Group>Session</Group>
    <IsReadOnly>true</IsReadOnly>
  </Option>
</ArrayOfOption>

我无法找到序列化程序无法正确转换列表的原因。也没有错误消息。

如果需要,此处是项目的GitHub链接。

1 个答案:

答案 0 :(得分:1)

经过大量的搜索和实验,我找到了答案,所以我把它放在这里以防其他人有同样的问题:

  • 首先,我使用XMLSerializer来序列化/反序列化对象,但是当错误发生时,输出上只有一行说错了,这不是很有帮助。
  • 我尝试在所有XML序列化错误上启用异常抛出,但没有抛出任何错误。
  • 然后我切换到DataContractSerializer,这给了我更多关于发生了什么的信息。

原来,对于未知类型,例如List<String>(奇怪的是,MSDN称它是已知类型),必须为序列化器和解串器提供类型。 使用DataContractSerializer,可以通过使用[KnownType(typeof(List<String>))][Serializable] [DataContract] [KnownType(typeof(List<String>))] [KnownType(typeof(DoubleInterval))] public class Option : IOption { } 添加到对象的定义来完成。

就我而言,这就是我班级的开始:

DataContractSerializer

{{1}}将使用属性将对象映射到XML数据。