繁体   English   中英

将基本类型的C#Xml-Serialization转换为派生类型-哪个TypeName属性定义获胜?

[英]C# Xml-Serialization of abstract base type into derived type - which TypeName property definition wins?

我的情况:

我有一个用XmlElement标记修饰的属性定义的对象,并且该属性具有我定义的类型,其中一些类型被抽象为抽象,并被设置为各个派生类型。 我想使用XmlSerializer将整个对象序列化为XML,并且所有抽象的属性都应序列化为元素,并将TypeName设置为派生类型的TypeName。

这是对象的结构示例:

[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
    [XmlElement(Type = typeof(DerivedClass))]
    public BaseClass TheBase { get; set; }
}

[XmlInclude(typeof(DerivedClass))]
public abstract class BaseClass
{
    [XmlAttribute("AnAttribute")]
    public string AnAttribute { get; set; }

    [XmlElement("ANELEMENT")]
    public string AnElement { get; set; }

}

[XmlType(TypeName = "DERIVEDCLASS")]
public class DerivedClass : BaseClass
{
    [XmlElement("ANOTHERELEMENT")]
    public string AnotherElement { get; set; }

}

但是请注意,当我创建MainObject的新实例时,填充它的属性并对其进行序列化,这就是生成的XML的样子:

<MAINOBJECT>
    <BaseClass AnAttribute="">
            <ANELEMENT/>
            <ANOTHERELEMENT/>
    </BaseClass>
</MAINOBJECT>

我想要的是:

<MAINOBJECT>
    <DERIVEDCLASS AnAttribute="">
            <ANELEMENT/>
            <ANOTHERELEMENT/>
    </DERIVEDCLASS>
</MAINOBJECT>

任何线索我在这里做错了吗?

将XmlElement名称添加到TheBase中的MainObject ,如下所示:

[XmlType(TypeName = "MAINOBJECT")]
public class MainObject
{
    [XmlElement("DERIVEDCLASS", Type = typeof(DerivedClass))]
    public BaseClass TheBase { get; set; }
}

在我看来,最好的解决方案是实现IXmlSerializable接口,以便您可以完全控制对象的序列化方式。 当然,这需要更多的工作,但是如果您对这样的要求有些不寻常,那么您可能还会遇到更多的怪癖,而标准XmlSerializer却无法为您效劳。

这里有一个很好的教程: 如何正确实现IXmlSerializable

另外,这里有一些很好的信息: 实现IXmlSerializable的正确方法?

也许不是最好的解决方案,但是:

class Program
    {
        static void Main(string[] args)
        {
            XmlAttributes attrs = new XmlAttributes();

            XmlElementAttribute attr = new XmlElementAttribute();
            attr.ElementName = "DerivedClass";
            attr.Type = typeof(DerivedClass);

            attrs.XmlElements.Add(attr);

            XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();

            attrOverrides.Add(typeof(MainObject), "TheBase", attrs);

            XmlSerializer s = new XmlSerializer(typeof(MainObject), attrOverrides);

            StringWriter writer = new StringWriter();

            MainObject mo = new MainObject { TheBase = new DerivedClass { AnAttribute = "AnAttribute", AnElement = "AnElement", AnotherElement = "AotherElement" } };

            s.Serialize(writer, mo);
            Console.Write(writer.ToString());
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM