programing

XmlSerializer에서 Null 값 유형을 내보내지 않도록 억제

mailnote 2023. 10. 23. 22:00
반응형

XmlSerializer에서 Null 값 유형을 내보내지 않도록 억제

Nullable XmlElement로 표시된 다음 Amount value type 속성을 고려하십시오.

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

nullable value type을 null로 설정하면 C# XmlSerializer 결과가 다음과 같이 나타납니다.

<amount xsi:nil="true" />

이 요소를 방출하는 것보다 Xml Serializer가 요소를 완전히 억제했으면 합니다. 왜죠?우리는 Authorize를.온라인 결제를 위한 NET 및 Authorize.이 null 요소가 있으면 NET에서 요청을 거부합니다.

현재 해결 방법은 Amount value type 속성을 직렬화하지 않는 것입니다.대신에 우리는 금액을 기준으로 하고 대신 직렬화되는 보완 속성인 Serializable 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); }
}

물론, 이것은 단지 해결책일 뿐입니다.null value 타입 요소가 방출되는 것을 억제하는 더 깨끗한 방법이 있습니까?

추가 시도:

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

프레임워크의 일부에서 인식되는 여러 패턴이 있습니다.참고로.XmlSerializer또한 찾습니다.public bool AmountSpecified {get;set;}.

전체 예제(또한 다음으로 전환)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);
    }
}

MSDN의 Should Serialize*에 대한 자세한 정보.

또한 얻을 수 있는 대안이 있습니다.

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

사용하다

[XmlElement("amount", IsNullable = false)]
public string SerializableAmount
{
    get { return this.Amount == null ? "" : this.Amount.ToString(); }
    set { this.Amount = Convert.ToDouble(value); }
}
public class XmlNullable<T>
    where T : struct
{
    [XmlText]
    public T Value { get; set; }

    public static implicit operator XmlNullable<T>(T value)
    {
        return new XmlNullable<T>
        {
            Value = value
        };
    }

    public static implicit operator T?(XmlNullable<T> value)
    {
        if (value == null)
        {
            return null;
        }

        return value.Value;
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}

성공적으로 테스트됨

  • int
  • bool
  • enum와 함께[XmlEnum]기여하다
  • 직렬화 및 역직렬화

예:

[XmlRoot("example")]
public class Example
{
    [XmlElement("amount")]
    public XmlNullable<double> Amount { get; set; }
}

Null 속성이 무시됨:

new Example()

XML을 생성하게 됩니다.

<example />

값이 있는 속성은 이전과 마찬가지로 XML로 이동합니다.

var example = new Example
{
    Amount = 3.14
};

XML을 생성하게 됩니다.

<example>
  <amount>3.14</amount>
</example>

시도해 볼 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/1296468/suppress-null-value-types-from-being-emitted-by-xmlserializer

반응형