C# 禁止 XmlSerializer 发出空值类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1296468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:49:13  来源:igfitidea点击:

Suppress Null Value Types from Being Emitted by XmlSerializer

c#xmlxml-serialization

提问by Ben Griswold

Please consider the following Amount value type property which is marked as a nullable XmlElement:

请考虑以下标记为可为空的 XmlElement 的 Amount 值类型属性:

[XmlElement(IsNullable=true)] 
public double? Amount { get ; set ; }

When a nullable value type is set to null, the C# XmlSerializer result looks like the following:

当可空值类型设置为 null 时,C# XmlSerializer 结果如下所示:

<amount xsi:nil="true" />

Rather than emitting this element, I would like the XmlSerializer to suppress the element completely. Why? We're using Authorize.NET for online payments and Authorize.NET rejects the request if this null element exists.

我希望 XmlSerializer 完全抑制该元素,而不是发射此元素。为什么?我们使用 Authorize.NET 进行在线支付,如果此空元素存在,Authorize.NET 将拒绝请求。

The current solution/workaround is to not serialize the Amount value type property at all. Instead we have created a complementary property, SerializableAmount, which is based on Amount and is serialized instead. Since SerializableAmount is of type String, which like reference types are suppressed by the XmlSerializer if null by default, everything works great.

当前的解决方案/解决方法是根本不序列化 Amount 值类型属性。相反,我们创建了一个补充属性 SerializableAmount,它基于 Amount 并被序列化。由于 SerializableAmount 是 String 类型,如果默认情况下为 null,则 XmlSerializer 会抑制引用类型,因此一切正常。

/// <summary>
/// Gets or sets the amount.
/// </summary>
[XmlIgnore]
public double? Amount { get; set; }

/// <summary>
/// Gets or sets the amount for serialization purposes only.
/// This had to be done because setting value types to null 
/// does not prevent them from being included when a class 
/// is being serialized.  When a nullable value type is set 
/// to null, such as with the Amount property, the result 
/// looks like: &gt;amount xsi:nil="true" /&lt; which will 
/// cause the Authorize.NET to reject the request.  Strings 
/// when set to null will be removed as they are a 
/// reference type.
/// </summary>
[XmlElement("amount", IsNullable = false)]
public string SerializableAmount
{
    get { return this.Amount == null ? null : this.Amount.ToString(); }
    set { this.Amount = Convert.ToDouble(value); }
}

Of course, this is just a workaround. Is there a cleaner way to suppress null value type elements from being emitted?

当然,这只是一种解决方法。有没有更干净的方法来抑制空值类型元素的发出?

采纳答案by Marc Gravell

Try adding:

尝试添加:

public bool ShouldSerializeAmount() {
   return Amount != null;
}

There are a number of patterns recognised by parts of the framework. For info, XmlSerializeralso looks for public bool AmountSpecified {get;set;}.

框架的某些部分可以识别许多模式。有关信息,XmlSerializer还可以查找public bool AmountSpecified {get;set;}.

Full example (also switching to decimal):

完整示例(也切换到decimal):

using System;
using System.Xml.Serialization;

public class Data {
    public decimal? Amount { get; set; }
    public bool ShouldSerializeAmount() {
        return Amount != null;
    }
    static void Main() {
        Data d = new Data();
        XmlSerializer ser = new XmlSerializer(d.GetType());
        ser.Serialize(Console.Out, d);
        Console.WriteLine();
        Console.WriteLine();
        d.Amount = 123.45M;
        ser.Serialize(Console.Out, d);
    }
}

More information on ShouldSerialize* on MSDN.

有关MSDN上的ShouldSerialize* 的更多信息。

回答by mko

There is also an alternative to get

还有一种替代方法可以获得

 <amount /> instead of <amount xsi:nil="true" />

Use

[XmlElement("amount", IsNullable = false)]
public string SerializableAmount
{
    get { return this.Amount == null ? "" : this.Amount.ToString(); }
    set { this.Amount = Convert.ToDouble(value); }
}

回答by Nicolas Battaglia

you can try this :

你可以试试这个:

xml.Replace("xsi:nil=\"true\"", string.Empty);

xml.Replace("xsi:nil=\"true\"", string.Empty);