DataContract Serializer数组节点名称'd3p1'

时间:2013-06-05 17:14:42

标签: .net xml asp.net-web-api xml-serialization

有人可以告诉我“d3p1”节点名称在这个中意味着什么吗?

    <ActionMessage>
        <Data xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
          <d3p1:anyType i:type="Agreement">
 </d3p1:anyType>
      <d3p1:anyType i:type="Agreement"> shortened

我收到了许多“看起来很难看”和“如果d3p1发生了什么变化”这个对我的asp webapi项目中的默认序列化的评论。我说它的机器可读性很好。但我很好奇为什么会这样。

以下是详细信息,我在控制器上有一个GET动词,它返回一个ActionMessage的可枚举

 public IEnumerable<ActionMessage> Get(Guid)

ActionMessage不能是通用的(如果这甚至会有帮助),因为列表将包含不同泛型类型的操作消息。 “newagreement”,“keychange”等。

看起来像ActionMessage<NewAgreement>ActionMessage<KeyChange>等等。 get中没有办法执行此操作,因为get返回许多“类型”的操作消息。基类或接口之外。 I.E. ActionMessage<IMessage>但这些消息没有任何共同之处。

这是现在的动作消息。

 public class ActionMessage
{
    [DataMember]
    public Status Status { get; set; }
    [DataMember]
    [XmlElement(ElementName = "Agreement")]
    [XmlArrayItem(ElementName = "testnode")]
    public List<object> Data { get; set; }
    [DataMember]
    public MessageTypes Type { get; set; }
    [DataMember]
    public Guid Id { get; set; }
}

请注意,“麻烦的”XML来自数据属性。

思考? XML人类可读性是否重要?我应该经历从datacontract序列化器切换到xml序列化器的痛苦吗?这可能会启用元素名称属性,但我更喜欢将其全部保留下来,虽然我可以完全控制生成的XML,但我真的需要,还是我真的在乎?

1 个答案:

答案 0 :(得分:4)

在努力解决这一问题后,我得出的结论是,通常最好尽可能明确地使用数据合同。在这种情况下,我会将List<object> Data拆分为多个显式列表,即List<Agreement> Agreements; List<KeyChange> KeyChanges;等等。生成的XML可能如下所示:

<ActionMessage>
    <Status>...</Status>
    <Agreements>
        <Agreement>...</Agreement>
    </Agreements>
    <KeyChanges/>
    ...
</ActionMessage>

某些元素将为空(您可以将序列化程序配置为省略这些元素),但每个元素都是显式的,易于阅读,解析和反序列化。更重要的是,模式的消费者确切地知道会发生什么。

还有另一种选择,那就是定义AgreementKeyChange等都可以实现的某种界面(例如'IData')并将List<object> Data更改为{ {1}}。它会产生稍微漂亮的XML文档,但您必须维护已知类型的列表,以确保可以反序列化所有实现。 XML看起来像这样:

List<IData> Data

然而,这会导致脆弱的反序列化,并且可能导致消息的向前/向后兼容性出现问题。