如何序列化基类型集合,并在易于阅读的XML中查看具体类型

Jas*_*yne 4 c# xml wcf serialization datacontractserializer

我有一个List,其中填充了子类BaseType的各种具体类型的对象

我正在使用WCF DataContractSerializer

<Children>
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
              i:type="d3p1:ConcreteTypeA"></BaseType>
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
              i:type="d3p1:ConcreteTypeB"></BaseType>
</Children>
Run Code Online (Sandbox Code Playgroud)

有没有办法让这个生成

<Children>
    <ConcreteTypeA/>
    <ConcreteTypeB/>
</Children>
Run Code Online (Sandbox Code Playgroud)

真正的目标是让用户生成一些XML以加载到内存中,并且用户具有技能级别,要求他们提供原始XML并不会成功.

Jos*_*osh 7

DataContractSerializer不是为了让您控制输出而设计的.它被设计为快速,隐式,并且易于将类归类.

你想要的是XmlSerializer.这使您可以更好地控制XML输出.

请注意,在我下面的示例中,我指定了很多可以从属性名称中推断出来的东西,但只是为了让您感觉可以在属性中覆盖它们.事实上,我认为如果删除了所有属性并且应用了一些KnownTypeAttributes但我还没有测试它,那么整个类将序列化很好.我不知道这是否会为您提供您所描述的确切XML(它将在Children之上创建一个根元素),但希望这会让您朝着正确的方向前进.

控制XML序列化的属性

[XmlRoot(Namespace="")]
public class MyClass {

    [XmlArray("Children")]
    [XmlArrayItem("ConcreteTypeA", typeof(ConcreteTypeA))]
    [XmlArrayItem("ConcreteTypeB", typeof(ConcreteTypeB))]
    public BaseType[] Children {
        get;
        set;
    }

}

public class BaseType {
}

public class ConcreteTypeA : BaseType {
}

public class ConcreteTypeB : BaseType {
}
Run Code Online (Sandbox Code Playgroud)

编辑:我刚测试,它产生的东西非常接近你所寻求的.

void Main()
{

    var mc = new MyClass();
    mc.Children = new BaseType[] {
        new ConcreteTypeA(),
        new ConcreteTypeB(),
        new ConcreteTypeA(),
        new ConcreteTypeB()
    };

    var serializer = new XmlSerializer(typeof(MyClass));

    using ( var str = new StringWriter() ) {
        serializer.Serialize(str, mc);
        str.ToString().Dump();
    }

}
Run Code Online (Sandbox Code Playgroud)

...产生......(从顶部删除无用的xmlns)

<MyClass>
  <Children>
    <ConcreteTypeA />
    <ConcreteTypeB />
    <ConcreteTypeA />
    <ConcreteTypeB />
  </Children>
</MyClass>
Run Code Online (Sandbox Code Playgroud)