【问题标题】:Deserializing an object from XML in C# with derived classes在 C# 中使用派生类从 XML 反序列化对象
【发布时间】:2020-06-12 08:25:15
【问题描述】:

我在下面有一个非常简单的 XML 文件:

<Job Name="test">
    <Pages>
        <MainPage Name="page1"/>
    </Pages>
</Job>

'MainPage'是PageBase的派生类,我的类结构如下

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

    [XmlElement]
    public List<PageBase> Pages { get; set; }
}

[XmlInclude(typeof(MainPage))]
[XmlInclude(typeof(SubPage))]
public abstract class PageBase
{
    [XmlAttribute]
    public string Name { get; set; }        
}

public class MainPage : PageBase
{

}

public class SubPage : PageBase
{

}

这是我用来反序列化的示例代码:

var xml = "<Job Name=\"test\"><Pages><MainPage Name=\"page1\"></MainPage></Pages></Job>";
MemoryStream str = new MemoryStream();
StreamWriter writer = new StreamWriter(str);
writer.Write(xml);
writer.Flush();
str.Position = 0;

var serializer = new XmlSerializer(typeof(Job));
var job = (Job)serializer.Deserialize(str);

但是,我收到以下错误 - 尽管在 PageBase 类型中包含了我的 XmlInclude。我究竟做错了什么? DotNetFiddle:https://dotnetfiddle.net/UucVmX

运行时异常(第 18 行):XML 文档中存在错误(1, 19).

堆栈跟踪:

[System.InvalidOperationException:指定的类型是抽象的: name='PageBase', namespace='', at .] at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read4_PageBase(布尔 isNullable, Boolean checkType) 在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read5_Job(布尔 isNullable, Boolean checkType) 在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read6_Job()

[System.InvalidOperationException: XML 文档中存在错误 (1, 19).] 在 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、字符串 encodingStyle、XmlDeserializationEvents 事件)
在 System.Xml.Serialization.XmlSerializer.Deserialize(Stream 流)
在 Program.Main() :第 18 行

【问题讨论】:

  • 这能回答你的问题吗? XML Serialization and Inherited Types 这个thread 也会有帮助
  • 很遗憾没有,因为我已经有 XmlInclude,但它们不起作用
  • 你应该为抽象类型实现IXmlSerializable,就像在提到的线程中解释的那样
  • XmlInclude 的目的不是让这个场景“正常工作”,而不必实现这个接口吗?
  • 在您的类中创建一些测试数据,然后序列化以查看 xml 输出和您的代码生成的内容。 include 需要 type 属性。

标签: c# xml serialization


【解决方案1】:

将您的 XML 更改为:

<Job Name="test">
    <Pages>
        <PageBase xsi:type="MainPage" Name="page1"/>
    </Pages>
</Job>

首先尝试序列化您的对象并检查它生成的 XML。您应该看到 XML-Element 将是 PageBase 和 xsi:type="MainPage"。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2017-06-24
    相关资源
    最近更新 更多