简体   繁体   English

避免在.Net DataContractSerializer中使用“http://www.w3.org/2001/XMLSchema-instance”命名空间

[英]Avoiding using the “http://www.w3.org/2001/XMLSchema-instance” namespace with .Net DataContractSerializer

I have a series of classes that I am converting to XML using .NET's DataContractSerializer in .NET 4.0. 我有一系列的类,我在.NET 4.0中使用.NET的DataContractSerializer转换为XML。 The serialisation is working fine, and I can parse the XML and recreate the .NET objects later without any difficulty. 序列化工作正常,我可以解析XML并在以后重新创建.NET对象而没有任何困难。

However, most of the DataMember's are not required. 但是,大多数DataMember都不是必需的。 [DataMember(IsRequired = false)]. [DataMember(IsRequired = false)]。 This works great on de-serializing the XML, where you can then just miss the XML node out of the document, but when serializing an exisiting object into XML, the DataContractSerializer insists on writing out properties that have null values as nodes with an attribute eg 这非常适用于反序列化XML,然后您可以在文档中错过XML节点,但在将现有对象序列化为XML时,DataContractSerializer坚持将具有空值的属性写为具有属性的节点,例如

[DataContract(Name = "response", Namespace = "http://domain.com/name")]
public class MyResponseClass
{
    [DataMember(Name = "count", IsRequired = true, Order = 0)]
    public int Count { get; set; }

    [DataMember(Name = "info", IsRequired = false, Order = 1)]
    public InfoClass Info { get; set; }

    [DataMember(Name = "metadata", IsRequired = false, Order = 2)]
    public MetadataList Metadatas { get; set; }

}

can be serialised from 可以序列化

<response xmlns="http://domain.com/name">
    <count>4</count>
</response>

However, if I serialise the object, it creates: 但是,如果我序列化对象,它会创建:

<response xmlns="http://domain.com/name" xmlns:i="http://www.w3.org/2001/XmlSchema-instance">
    <count>4</count>
    <info i:nil="true" />
    <metadata i:nil="true" />
</response>

Is there any way to get the DataContractSerializer to not write the node instead, when it has a null value? 当它具有空值时,有没有办法让DataContractSerializer不写节点?

Use EmitDefaultValue = false to skip default values in XML: 使用EmitDefaultValue = false跳过XML中的默认值:

[DataContract(Name = "response", Namespace = "http://domain.com/name")]
public class MyResponseClass 
{
    [DataMember(Name = "count", IsRequired = true, Order = 0, EmitDefaultValue = false)]
    public int Count { get; set; }

    [DataMember(Name = "info", IsRequired = false, Order = 1, EmitDefaultValue = false)]
    public InfoClass Info { get; set; }

    [DataMember(Name = "metadata", IsRequired = false, Order = 2, EmitDefaultValue = false)]
    public MetadataList Metadatas { get; set; }
}

to remove xmlns:i="http://www.w3.org/2001/XmlSchema-instance" you have to use for example Replace() like in the following example 删除xmlns:i="http://www.w3.org/2001/XmlSchema-instance"你必须使用例如Replace() ,如下例所示

public void Write(string filePath, MyResponseClass myResponse)
{
    var serializer = new DataContractSerializer(typeof(MyResponseClass));

    var sb = new StringBuilder();
    using (var writer = new StringWriter(sb))
    using (var xmlWriter = XmlWriter.Create(writer))
    {
        serializer.WriteObject(xmlWriter, myResponse);
    }

    using (StreamWriter stream = new StreamWriter(filePath))
    {
        sb = sb.Replace(" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
        stream.Write(sb);
    }
}

with regards :) 带着敬意 :)

(I posted this answer accidentally in the wrong question, but I think it is helpful here, too, so I don't delete it for now) (我在错误的问题中意外地发布了这个答案,但我认为这也很有用,所以我现在不删除它)

[DataContract(Namespace = "")]

on top of each class makes it a lot nicer. 在每个班级的顶部使它更好。 It removes the datacontract namespaces and the ugly node prefixes. 它删除了datacontract命名空间和丑陋的节点前缀。 However, the standard namespace stays. 但是,标准名称空间保持不变。 That was ok for my case. 这对我的情况来说没问题。

Before: 之前:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://schemas.datacontract.org/2004/07/MyClassname">
  <prop1>true</prop1>
  <prop2 xmlns:d2p1="http://schemas.datacontract.org/2004/07/MySubclassname">
    <d2p1:sub>true</d2p1:sub>
  </prop2>
</root>

After: 后:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <prop1>true</prop1>
  <prop2>
    <sub>true</sub>
  </prop2>
</root>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 DataContractSerializer 时删除 xmlns:i=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; - remove xmlns:i=“http://www.w3.org/2001/XMLSchema-instance” when using DataContractSerializer 从名称空间&#39;http://www.w3.org/2001/XMLSchema-instance&#39;期望元素&#39;CustomerLeads&#39; - Expecting element 'CustomerLeads' from namespace 'http://www.w3.org/2001/XMLSchema-instance' 删除 p2:type="&lt;<type> &gt;" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" 来自 xml</type> - Remove p2:type="<<type>>" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" from xml 具有“ http://www.w3.org/2001/XMLSchema”名称空间的性能影响 - Performance impact of having “http://www.w3.org/2001/XMLSchema” namespace 元素http://www.w3.org/2001/XMLSchema:complexType在此上下文中无效 - Element http://www.w3.org/2001/XMLSchema:complexType is invalid in this context C#中的XML反序列化错误-InvalidOperationException: <element xmlns='http://www.w3.org/2001/XMLSchema'> 没想到 - XML Deserialization Error in C# - InvalidOperationException: <element xmlns='http://www.w3.org/2001/XMLSchema'> was not expected “'http://www.w3.org/XML/1998/namespace:lang' 属性未声明。” - “The 'http://www.w3.org/XML/1998/namespace:lang' attribute is not declared.” JWT Header 算法:“hs256”与“http://www.w3.org/2001/04/xmldsig-more#hmac-sha256”相同 - JWT Header algorithm: is "hs256" the same as "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256" DNX Core 5.0 JwtSecurityTokenHandler“ IDX10640:不支持算法:&#39;http://www.w3.org/2001/04/xmldsig-more#hmac-sha256&#39;” - DNX Core 5.0 JwtSecurityTokenHandler “IDX10640: Algorithm is not supported: 'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256'” SignedXml CanonicalizationMethod - http://www.w3.org/2006/12/xml-c14n11 - SignedXml CanonicalizationMethod - http://www.w3.org/2006/12/xml-c14n11
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM