Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何控制.NET DataContract序列化,使其使用XML属性而不是元素?_.net_Serialization_Xml Serialization_Datacontract - Fatal编程技术网

如何控制.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