有人可以告诉我“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,但我真的需要,还是我真的在乎?
答案 0 :(得分:4)
在努力解决这一问题后,我得出的结论是,通常最好尽可能明确地使用数据合同。在这种情况下,我会将List<object> Data
拆分为多个显式列表,即List<Agreement> Agreements
; List<KeyChange> KeyChanges
;等等。生成的XML可能如下所示:
<ActionMessage>
<Status>...</Status>
<Agreements>
<Agreement>...</Agreement>
</Agreements>
<KeyChanges/>
...
</ActionMessage>
某些元素将为空(您可以将序列化程序配置为省略这些元素),但每个元素都是显式的,易于阅读,解析和反序列化。更重要的是,模式的消费者确切地知道会发生什么。
还有另一种选择,那就是定义Agreement
,KeyChange
等都可以实现的某种界面(例如'IData')并将List<object> Data
更改为{ {1}}。它会产生稍微漂亮的XML文档,但您必须维护已知类型的列表,以确保可以反序列化所有实现。 XML看起来像这样:
List<IData> Data
然而,这会导致脆弱的反序列化,并且可能导致消息的向前/向后兼容性出现问题。