微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何从XML反序列化抽象类的具体实现

我有一个抽象类,有几个具体的实现.这需要序列化为XML才能发送到另一个系统 – 这很好.但是,我还需要能够反序列化相同的XML结构.无论我尝试什么,我似乎都无法做到这一点.我的班级结构如下:

抽象类:

[XmlIncludeAttribute(typeof(ConcreteFooOne))]
[XmlIncludeAttribute(typeof(ConcreteFooTwo))]
[XmlIncludeAttribute(typeof(ConcreteFooThree))]
[XmlRoot(ElementName = "FooData", Namespace="http://foo.bar")]
public abstract partial class AbstractFoo
{
    // Some abstract props etc.
}

具体类示例:

public partial class ConcreteFooOne : AbstractFoo
{
    // Some properties, constructor etc.
}

XML根示例:

<FooData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteFooOne" RequestResponse="Request" xmlns="http://foo.bar">

仅包含XML root作为示例,因为这似乎是问题所在.现在我可以序列化很好,但是在反序列化中,如果我通过传入抽象类型反序列化,我当然会得到一个异常,说明类型“AbstractFoo”是抽象的.所以我只是改变了逻辑,以便将具体类型(在这种情况下为ConcreteFooOne)传递给序列化器.现在我得到一个“http://foo.bar’\u0026gt;没想到”.我假设这是因为序列化程序不知道根节点应该是什么?

我在抽象类上定义了根节点,因为这对于所有具体实现都是相同的.具体类型由“RequestResponse”属性定义(或者如果存在,则xsi:type属性也可以工作,因为它给出了实际的类型名称).有没有办法让序列化程序获取抽象类所需的内容,或者我对此完全采用错误方法

>请注意,我不能过多地更改类结构,因为它非常基于第三方提供的某些XML模式.

在此先感谢任何人的帮助,我们将不胜感激.

解决方法:

将[XmlRoot(ElementName =“FooData”,Namespace =“http://foo.bar”)]添加到子类

这是我做的一个例子:

  [XmlIncludeAttribute(typeof(ConcreteFooOne))]
  [XmlIncludeAttribute(typeof(ConcreteFooTwo))]
  [XmlIncludeAttribute(typeof(ConcreteFooThree))]
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public abstract partial class AbstractFoo
  {
    // Some abstract props etc.
  }

  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooOne : AbstractFoo
  {
    public int MyProp { get; set; }
  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooTwo : AbstractFoo
  {

  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]
  public class ConcreteFooThree : AbstractFoo
  {

  }

  class Program
  {
    static void Main(string[] args)
    {
      var serializer = new System.Xml.Serialization.XmlSerializer(typeof(AbstractFoo));
      using (var stream = new FileStream("test.txt", FileMode.OpenorCreate))
      {
        serializer.Serialize(stream, new ConcreteFooOne() { MyProp = 10 });
        stream.Flush();
      }


      using (var stream = new FileStream("test.txt", FileMode.OpenorCreate))
      {
        var c = serializer.Deserialize(stream);
      }
    }
  }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。