有没有办法让DataContractSerializer输出更清晰的XML?

时间:2009-12-23 16:55:04

标签: c# xml datacontractserializer

使用DataContractSerializer序列化我的对象,我得到类似于

的输出
 <?xml version="1.0" encoding="utf-8" ?> 
 <AgentNotification xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/The.name.space.Notifications">
  <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" />        
 <_x003C_Email_x003E_k__BackingField>some@email.com</_x003C_Email_x003E_k__BackingField> 
  <_x003C_Name_x003E_k__BackingField>Random Person</_x003C_Name_x003E_k__BackingField> 
 <_x003C_Policies_x003E_k__BackingField>
 <PolicyNotification>
  <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
  <_x003C_ConfirmationNumber_x003E_k__BackingField>Some number</_x003C_ConfirmationNumber_x003E_k__BackingField>   
  </PolicyNotification>
 <PolicyNotification>
  </_x003C_Policies_x003E_k__BackingField>  
  </AgentNotification>

有没有办法输出只是

的标签
<Id>
<Name>

等,不需要用属性覆盖我的类?

如果没有办法确保每次正确的输出相同?因此,如果我使用它来渲染我的对象图是XML与文件生成的X *文档混搭,我将永远不会遇到我的节点更改名称并且文档空白正确的问题吗?

4 个答案:

答案 0 :(得分:9)

这种情况正在发生,因为您必须使用[Serializable]标记您的类型(例如AgentNotification)。当DataContractSerializer遇到标有[Serializable]但没有明确[DataContract]的类型时,会生成default contract类型,其类型与BinaryFormatter序列化类的方式相匹配,即序列化all member variables of a class — even variables marked as private - 按名称。对于auto-implemented properties,这意味着secret backing fields按名称序列化;他们的名字是你看到的特殊元素名称。

解决此问题的最简单方法是从类中删除[Serializable]属性。除非您实际使用BinaryFormatterSoapFormatter,否则几乎肯定不需要它。完成此操作后,DataContractSerializer现在将按名称序列化您的公共属性和字段,而不是按名称序列化公共和私有字段。

答案 1 :(得分:5)

当您使用autoproperties时,.NET会创建长元素名称(例如,_x003C_Created_x003E_k__BackingField)。

如果您将它们更改为具有支持字段的属性,则它们将使用您的支持字段名称。您可以在不向代码添加任何属性的情况下执行此操作。

(除此之外,只需在类定义中添加[DataContract]属性就可以大量整理XML - 尽管不完全。)

答案 2 :(得分:1)

DataContractSerializer将序列化所有公共属性(如果您未指定任何内容 - 从.NET 3.5 SP1开始可能),或者(我更喜欢的方法)您使用[DataMember]属性标记的任何内容。

因此,您可以做的最好的事情是使用[DataContract]属性标记您的班级,并使用[DataMember]属性在数据合同中标记您真正想要的所有成员(属性,字段等)

DataContractSerializer实际上不允许更多的控制 - 你可以非常清楚地定义(使用这种明确的“选择加入”方法)什么被序列化,但是你几乎没有控制权如何它被序列化。

但你真的需要吗?真的?

如果是这样,你可能不得不将XmlSerializer用于该序列化过程 - 在那里你可以更好地控制如何事物序列化(但作为一个缺点,XmlSerializer将序列化每个未明确标记[XmlIgnore]属性的公共属性 - “选择退出”方案。

查看Dan Rigsby的blog post关于DataContractSerializer和XmlSerializer之间的差异以及它们各自提供的内容。

答案 3 :(得分:0)

最后我遇到了同样的麻烦,所以你只需要将[DataContract]和[DataMember]添加到模型中。

相关问题