有没有办法使DataContractSerializer输出更干净的XML?

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

    some@email.com Random Person     Some number     

有没有办法输出正好的标签

   

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

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

发生这种情况是因为您必须使用[Serializable]标记您的类型(例如AgentNotification )。 当DataContractSerializer遇到标有[Serializable]但没有显式[DataContract]的类型时,它会生成一个类型的默认契约 ,该类型与BinaryFormatter序列化类的方式相匹配,即序列化类的所有成员变量 – 甚至标记为私有的变量 -按名字。 对于自动实现的属性 ,这意味着秘密支持字段按名称序列化; 他们的名字是你所看到的奇特的元素名称。

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

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

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

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

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

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

DataContractSerializer实际上并不允许更多的控制 – 您可以非常清楚地定义(使用这种明确的“选择加入”方法)序列化的内容,但您很少或根本无法控制它的序列化方式。

但你真的需要吗? 真?

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

查看Dan Rigsby的博客文章 ,了解DataContractSerializer和XmlSerializer之间的差异以及它们各自提供的内容。

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