如何控制.NET DataContract序列化,使其使用XML属性而不是元素?
如果我有一个标记为如何控制.NET DataContract序列化,使其使用XML属性而不是元素?,.net,serialization,xml-serialization,datacontract,.net,Serialization,Xml Serialization,Datacontract,如果我有一个标记为DataContract的类和一些标记有DataMember属性的属性,我可以轻松地将其序列化为XML,但它会创建如下输出: <Person> <Name>John Smith</Name> <Email>john.smith@acme.com</Email> <Phone>123-123-1234</Phone> </Person> 约翰·史密斯 厕所。
DataContract
的类和一些标记有DataMember
属性的属性,我可以轻松地将其序列化为XML,但它会创建如下输出:
<Person>
<Name>John Smith</Name>
<Email>john.smith@acme.com</Email>
<Phone>123-123-1234</Phone>
</Person>
约翰·史密斯
厕所。smith@acme.com
123-123-1234
我更喜欢的是属性,比如
<Person Name="John Smith" Email="john.smith@acme.com" Phone="123-123-1234" />
DataMember
属性允许我控制名称和顺序,但不允许将其序列化为元素或属性。我环顾四周,发现了DataContractFormat
和IXmlSerializable
,但我希望有一个更简单的解决方案
做这件事最简单的方法是什么?你不能用
DataContractSerializer来做这件事;如果需要属性,则需要使用XmlSerializer
。使用DataContractSerializer
类,允许使用XML规范中更严格的子集,这可以提高性能,并改进已发布服务的互操作性,但对XML格式的控制相对较少
如果您使用的是WCF服务,请查看允许您使用XmlSerializer
进行序列化的选项。您可以使用
DataContractSerializer-答案是
接管Xml序列化
通过实施
IXmlSerializable接口。对于
只写支持-您可以离开
ReadXml empty的实现,以及
为GetSchema返回null,然后
编写WriteXml的实现
详情如下:
public class MyPerson : IXmlSerializable
{
public string Name { get; set;}
public string Email { get; set;}
public string Phone { get; set;}
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) { }
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("name", Name);
writer.WriteAttributeString("email", Email);
writer.WriteAttributeString("phone", Phone);
}
}
如果您对JSON序列化也使用相同的类型,那么您仍然可以自由添加DataContract和DataMember属性—DataContractSerializer将仅在编写Xml时使用IXmlSerializable接口实现
我在博客上写过这方面的内容。在序列化/反序列化时,可以在属性和元素之间来回转换。以下内容适用于后者
private XmlReader AttributesToElements( Stream stream )
{
var root = XElement.Load( stream );
foreach ( var element in root.Descendants() ) {
foreach ( var attribute in element.Attributes() )
element.Add( new XElement( root.Name.Namespace + attribute.Name.LocalName, (string)attribute ) );
element.Attributes().Remove();
}
return root.CreateReader();
}
此外,我需要XML以这种方式工作,同时JSON继续工作。必须有一种简单的方法使其使用属性。我不关心web服务,我只是想以特定格式输出XML。您好,恐怕Greg是正确的-请参阅DataContractSerializer的限制。如果您不关心web服务,那么为什么要使用WCF?你只是想序列化一些类吗?如果是这样的话,那么就自己使用XmlSerializer。奇怪的是,WCF声称拥有所有这些enterop功能,却不能做到这一点。许多在线服务的模式都需要xml中的属性。我了解性能,但让我选择,这样我就可以与其他服务交谈。您确定DataContractSerializer
将调用此代码的WriteXml
方法吗?我知道-这似乎不太可能-但我刚刚在我们的公司博客上发布了一篇文章,您可以在那里下载显示其实际操作的源代码(使用它实现OpenSearch建议)。线索来自此MSDN内容:。是的,谢谢,似乎正确的实现应该使用XmlSchemaProviderAttribute才能被视为正确实现。这方面的问题之多令人难以置信-但我不得不说,最基本的解决方案对我们的代码产生了奇迹。至少这意味着您不必依赖XmlSerializer!@AndrasZoltan DataContractJsonSerializer将使用IXmlSerializable接口实现这对于阅读也很好,我只需设置XmlRoot
属性。例如:要解析
我使用了[XmlRoot(ElementName=“Fault”,Namespace="http://com.sap/aii/proxy/xiruntime/“”]公共类错误:IXmlSerializable