默认的XmlSerializer
是否能够将类属性序列化为Xml属性?
[MyClassTypeAttribute(ClassType.MyClass)]
public MyClass : BaseClass {
}
会转向
<myclass MyClassType="MyClass">
原因:
我有一个WCF服务,它通过相同的操作合同向我发送不同的对象,这些操作合同都来自BaseClass
。要知道它是哪种类型的对象并直接进行转换(然后将其序列化为Xml以便在文档中写入),我想要一些'type'属性(enum
)。
当然,一种可能性是将属性声明为XmlAttribute
[XmlAttribute(params)]
public MyClassType { get; set; }
问题在于:XmlSerializer
(DataContractSerializer
以及AFAIK)迫使我在每个属性上都有setter
。我知道我可以将setter
声明为protected
并且它仍然有效( XmlSerializer
,你顽皮的小事),但是不喜欢那个解决方案,因为1)我认为有一个原因是我能够通常忽略POCO中的setter,2)将某些属性声明为XmlAttributes
而将其他属性声明为XmlElements
令人困惑(这就像放置狗和猫进入猫炖牛肉。
(另外,是否可以强制派生类声明某些属性?)
[abstract MyClassTypeAttribute]
答案 0 :(得分:0)
如果是关于你班级的类型的话就是一个例子:
[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);
}
}
}
代码将序列化并包含type属性,当您反序列化时,您将获得正确的实例。