反序列化派生类型



我以为我终于理解了XmlSerialization,但我最后的方法让我觉得自己完全是个新手。我的意图是创建一个序列化和反序列化某种配置的框架。因此,我创建了一个配置类,如下所示:

/// <summary>
/// Application-wide configurations that determine how to transform the features. 
/// </summary>
[XmlRoot(Namespace = "baseNS")]
public class Config
{
    /// <summary>
    /// List of all configuration-settings of this application
    /// </summary>
    [System.Xml.Serialization.XmlElement("Setting")]
    public List<Setting> Settings = new List<Setting>();
}

现在我需要某种配置,它定义了一个自定义设置列表。

/// <summary>
/// Application-wide configurations that determine how to transform the features. 
/// </summary>
[System.Xml.Serialization.XmlRoot("Config", Namespace = "baseNS")]
[System.Xml.Serialization.XmlInclude(typeof(BW_Setting))]
public class BW_Config : Config { 
    // nothing to add, only needed to include type BW_Setting
}

/// <summary>
/// Provides settings for one single type of source-feature specified by the <see cref="CQLQuery"/>-property. Only one target-featureType is possible for every setting. 
/// However settings for different targetTypes may have the same source-type provided. 
/// </summary>
[System.Xml.Serialization.XmlRoot("Setting", Namespace = "anotherNS")]
public class BW_Setting : Setting {
    // add and modify some attributes
}

据我所知,我已经将XmlInclude属性放在基类上(正在设置)。因此,Setting和BW_Setting位于不同的程序集中,后者取决于前者。我不能使用这种方法,因为我会得到一个圆参考。

这是实际序列化程序的代码:

XmlSerializer ser = new XmlSerializer(typeof(BW_Config));
BW_Config c = new BW_Config();
c.Settings.Add(new BW_Setting());
((BW_Setting)c.Settings[0]).CQLQuery = "test";

现在,当执行上述操作时,我得到错误"Type BW_Setting was not expected. Use XmlInclude..."我可以更改自定义程序集中的所有内容,但因此基本程序集属于框架,我无法更改它。你能帮我完成序列化(和反序列化)工作吗?

我最终通过定义一些覆盖来实现它:

// determine that the class BW_Setting overrides the elements within "Settings"
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(
    typeof(Config), 
    "Settings", new XmlAttributes { 
        XmlElements = { 
            new XmlElementAttribute("Setting", typeof(BW_Setting)) } });
XmlSerializer ser = new XmlSerializer(typeof(Config), overrides);

这会产生以下输出

<?xml version="1.0"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="baseNS">
  <Setting id="0">
    <CQLQuery>test</CQLQuery>
  </Setting>
</Config>

唯一令人不快的是XML中标记Setting的名称空间丢失了。然而,反序列化也起作用,所以这并不那么烦人。

最新更新