C# 如何从XML反序列化抽象类的具体实现
我有一个抽象类,有几个具体的实现。这需要序列化为XML以便发送到另一个系统-这工作正常。但是,我还需要能够反序列化相同的XML结构。不管我怎么做,我似乎都做不到。我的班级结构如下: 抽象类:C# 如何从XML反序列化抽象类的具体实现,c#,.net,xml,serialization,abstract,C#,.net,Xml,Serialization,Abstract,我有一个抽象类,有几个具体的实现。这需要序列化为XML以便发送到另一个系统-这工作正常。但是,我还需要能够反序列化相同的XML结构。不管我怎么做,我似乎都做不到。我的班级结构如下: 抽象类: [XmlIncludeAttribute(typeof(ConcreteFooOne))] [XmlIncludeAttribute(typeof(ConcreteFooTwo))] [XmlIncludeAttribute(typeof(ConcreteFooThree))] [XmlRoot(Eleme
[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.
}
<FooData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteFooOne" RequestResponse="Request" xmlns="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.
}
public partial class ConcreteFooOne : AbstractFoo
{
// Some properties, constructor etc.
}
<FooData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteFooOne" RequestResponse="Request" xmlns="http://foo.bar">
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.
}
<FooData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ConcreteFooOne" RequestResponse="Request" xmlns="http://foo.bar">
仅包括XML根作为示例,因为这似乎是问题所在。现在我可以很好地序列化,但是在反序列化上,如果我通过传递抽象类型进行反序列化,我当然会得到一个异常,声明类型“AbstractFoo”是抽象的。因此,我只是更改了逻辑,以便将具体类型(本例中为ConcreteFooOne)传递给序列化程序。现在我得到了一个“http://foo.bar“>并非预期”。我认为这是因为序列化程序不知道根节点应该是什么
我在抽象类上定义了根节点,因为这对于所有具体实现都是相同的。具体类型由“RequestResponse”属性定义(或者xsi:type属性也可以工作,如果它提供了实际的类型名称)。有没有一种方法可以让序列化程序从抽象类中提取所需的内容,或者我在这方面完全走错了方向
- 请注意,我不能对类结构进行太多更改,因为它非常接近于第三方提供的一些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.
}
[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);
}
}
}
很简单,在客户端反序列化时,定义一个
XmlSerializer
如下:
XmlSerializer xs= new XmlSerializer (typeof (AbstractFoo),
new Type[] { typeof (ConcreteFooOne), typeof (ConcreteFooTwo) } );
然后您可以尝试:
//it instantiate the correct class, need a streamreader
var myclass = xs.Deserialize(reader);
if (myclass is ConcreteFooOne)
//do something
if (myclass is ConcreteFooTwo)
//do something
我刚刚知道这会有用的,谢谢。如果我可以只在抽象类上定义“XmlRoot”属性就好了,因为不管有什么实现,它都是相同的。您知道实现这一点的方法吗,还是我必须在任何具体的类中不断复制“XmlRoot”?不,您不能只在基类中这样做,您可以检查属性的内在性问题