You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#反序列化含派生类的XML时出现异常,求排查解决

解决XML反序列化抽象基类的异常问题

你遇到的这个运行时异常,核心问题出在Job类中Pages属性的XML序列化特性配置和你的XML结构不匹配,具体来说:

你的Job类里给Pages属性标记了[XmlElement],这个特性会告诉XmlSerializer:把List中的每个PageBase派生类实例,直接作为<Job>节点的直接子元素来处理。但你的XML结构却是把<MainPage>放在<Pages>这个容器节点内部,两者的结构对应关系对不上,哪怕你已经在PageBase上添加了[XmlInclude],序列化器也无法正确解析节点关系,最终抛出抽象类无法实例化的错误。

修复方案

把Job类中Pages属性的[XmlElement]特性替换为[XmlArray](用来指定容器节点),配合[XmlArrayItem]明确允许的派生类型(和[XmlInclude]功能互补,也可以只保留[XmlArray],因为已经有XmlInclude了)。

修改后的Job类代码如下:

public class Job
{
    [XmlAttribute]
    public string Name { get; set; }

    // 用XmlArray指定容器节点名为Pages,对应XML中的<Pages>标签
    [XmlArray("Pages")]
    // 可选:明确声明允许的派生类型,和XmlInclude效果一致,二选一或并存都可
    [XmlArrayItem(typeof(MainPage))]
    [XmlArrayItem(typeof(SubPage))]
    public List<PageBase> Pages { get; set; }
}

补充说明

  • 你在PageBase上添加的[XmlInclude(typeof(MainPage))]和[XmlInclude(typeof(SubPage))]是完全正确的,这部分不需要修改,它负责告诉序列化器抽象基类PageBase有哪些具体的派生类型需要被识别。
  • 如果你不想修改C#代码,也可以调整XML结构,去掉<Pages>容器节点,让<MainPage>直接作为<Job>的子元素,这样原有的[XmlElement]特性就能正常工作,调整后的XML如下:
    <Job Name="test">
        <MainPage Name="page1"></MainPage>
    </Job>
    

按照第一种方案修改后,再运行你的反序列化代码,就能正确解析XML并得到预期的Job实例了。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:12:43