5

有人能告诉我“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 中执行此操作。在基类或接口之外。IEActionMessage<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 来自 data 属性。

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

4

1 回答 1

4

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

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

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

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

<ActionMessage>
    <Status>...</Status>
    <Data>
        <IData xsi:type="Agreement">..</IData>
        <IData xsi:type="KeyChange">..</IData>
    </Data>
    <KeyChanges/>
    ...
</ActionMessage>

但是,这会导致反序列化变得脆弱,并可能导致消息的向前/向后兼容性问题。

于 2013-06-05T19:00:00.100 回答