XmlSerializer 不包含非字符串元素

XmlSerializer does not include non string elements

这来自 WSDL 文档:

<s:complexType name="ResponseMsg">
<s:all>
<s:element minOccurs="0" maxOccurs="1" name="Responsestatus" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="CurBalance" type="s:double" />
<s:element minOccurs="0" maxOccurs="1" name="AvlBalance" type="s:double" />
<s:element minOccurs="1" maxOccurs="1" name="Acknowledgement" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="LoadAmount" type="s:double" />
<s:element minOccurs="0" maxOccurs="1" name="Bill_Amt_Approved" type="s:double" />
<s:element minOccurs="0" maxOccurs="1" name="Update_Balance" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="New_Balance_Sequence_Exthost" type="s:long" />
<s:element minOccurs="0" maxOccurs="1" name="CVV2_Result" type="s:string" /> <s:element minOccurs="0" maxOccurs="1" name="AvlBalance_GPS_STIP" type="s:double" /> <s:element minOccurs="0" maxOccurs="1" name="CurBalance_GPS_STIP" type="s:double" />
</s:all>
</s:complexType>

将 WSDL 添加到我的 Visual Studio 项目(添加服务引用)后,我得到:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.3752.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public partial class ResponseMsg : object, System.ComponentModel.INotifyPropertyChanged {
    
    private string responsestatusField;
    
    private double curBalanceField;
    
    private bool curBalanceFieldSpecified;
    
    private double avlBalanceField;
    
    private bool avlBalanceFieldSpecified;
    
    private string acknowledgementField;
    
    private double loadAmountField;
    
    private bool loadAmountFieldSpecified;
    
    private double bill_Amt_ApprovedField;
    
    private bool bill_Amt_ApprovedFieldSpecified;
    
    private int update_BalanceField;
    
    private bool update_BalanceFieldSpecified;
    
    private long new_Balance_Sequence_ExthostField;
    
    private bool new_Balance_Sequence_ExthostFieldSpecified;
    
    private string cVV2_ResultField;
    
    private double avlBalance_GPS_STIPField;
    
    private bool avlBalance_GPS_STIPFieldSpecified;
    
    private double curBalance_GPS_STIPField;
    
    private bool curBalance_GPS_STIPFieldSpecified;
    
    /// <remarks/>
    public string Responsestatus {
        get {
            return this.responsestatusField;
        }
        set {
            this.responsestatusField = value;
            this.RaisePropertyChanged("Responsestatus");
        }
    }
    
    /// <remarks/>
    public double CurBalance {
        get {
            return this.curBalanceField;
        }
        set {
            this.curBalanceField = value;
            this.RaisePropertyChanged("CurBalance");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool CurBalanceSpecified {
        get {
            return this.curBalanceFieldSpecified;
        }
        set {
            this.curBalanceFieldSpecified = value;
            this.RaisePropertyChanged("CurBalanceSpecified");
        }
    }
    
    /// <remarks/>
    public double AvlBalance {
        get {
            return this.avlBalanceField;
        }
        set {
            this.avlBalanceField = value;
            this.RaisePropertyChanged("AvlBalance");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool AvlBalanceSpecified {
        get {
            return this.avlBalanceFieldSpecified;
        }
        set {
            this.avlBalanceFieldSpecified = value;
            this.RaisePropertyChanged("AvlBalanceSpecified");
        }
    }
    
    /// <remarks/>
    public string Acknowledgement {
        get {
            return this.acknowledgementField;
        }
        set {
            this.acknowledgementField = value;
            this.RaisePropertyChanged("Acknowledgement");
        }
    }
    
    /// <remarks/>
    public double LoadAmount {
        get {
            return this.loadAmountField;
        }
        set {
            this.loadAmountField = value;
            this.RaisePropertyChanged("LoadAmount");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool LoadAmountSpecified {
        get {
            return this.loadAmountFieldSpecified;
        }
        set {
            this.loadAmountFieldSpecified = value;
            this.RaisePropertyChanged("LoadAmountSpecified");
        }
    }
    
    /// <remarks/>
    public double Bill_Amt_Approved {
        get {
            return this.bill_Amt_ApprovedField;
        }
        set {
            this.bill_Amt_ApprovedField = value;
            this.RaisePropertyChanged("Bill_Amt_Approved");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool Bill_Amt_ApprovedSpecified {
        get {
            return this.bill_Amt_ApprovedFieldSpecified;
        }
        set {
            this.bill_Amt_ApprovedFieldSpecified = value;
            this.RaisePropertyChanged("Bill_Amt_ApprovedSpecified");
        }
    }
    
    /// <remarks/>
    public int Update_Balance {
        get {
            return this.update_BalanceField;
        }
        set {
            this.update_BalanceField = value;
            this.RaisePropertyChanged("Update_Balance");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool Update_BalanceSpecified {
        get {
            return this.update_BalanceFieldSpecified;
        }
        set {
            this.update_BalanceFieldSpecified = value;
            this.RaisePropertyChanged("Update_BalanceSpecified");
        }
    }
    
    /// <remarks/>
    public long New_Balance_Sequence_Exthost {
        get {
            return this.new_Balance_Sequence_ExthostField;
        }
        set {
            this.new_Balance_Sequence_ExthostField = value;
            this.RaisePropertyChanged("New_Balance_Sequence_Exthost");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool New_Balance_Sequence_ExthostSpecified {
        get {
            return this.new_Balance_Sequence_ExthostFieldSpecified;
        }
        set {
            this.new_Balance_Sequence_ExthostFieldSpecified = value;
            this.RaisePropertyChanged("New_Balance_Sequence_ExthostSpecified");
        }
    }
    
    /// <remarks/>
    public string CVV2_Result {
        get {
            return this.cVV2_ResultField;
        }
        set {
            this.cVV2_ResultField = value;
            this.RaisePropertyChanged("CVV2_Result");
        }
    }
    
    /// <remarks/>
    public double AvlBalance_GPS_STIP {
        get {
            return this.avlBalance_GPS_STIPField;
        }
        set {
            this.avlBalance_GPS_STIPField = value;
            this.RaisePropertyChanged("AvlBalance_GPS_STIP");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool AvlBalance_GPS_STIPSpecified {
        get {
            return this.avlBalance_GPS_STIPFieldSpecified;
        }
        set {
            this.avlBalance_GPS_STIPFieldSpecified = value;
            this.RaisePropertyChanged("AvlBalance_GPS_STIPSpecified");
        }
    }
    
    /// <remarks/>
    public double CurBalance_GPS_STIP {
        get {
            return this.curBalance_GPS_STIPField;
        }
        set {
            this.curBalance_GPS_STIPField = value;
            this.RaisePropertyChanged("CurBalance_GPS_STIP");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool CurBalance_GPS_STIPSpecified {
        get {
            return this.curBalance_GPS_STIPFieldSpecified;
        }
        set {
            this.curBalance_GPS_STIPFieldSpecified = value;
            this.RaisePropertyChanged("CurBalance_GPS_STIPSpecified");
        }
    }
    
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

我将此代码添加到我的项目(在别处找到):

public static string ObjectToXml<T>(this T obj) where T : class
{
    var settings = new XmlWriterSettings
    {
        Indent = true,
        OmitXmlDeclaration = false,
        Encoding = Encoding.GetEncoding("UTF-8")
    };

    var namespaces = new XmlSerializerNamespaces();
    namespaces.Add(string.Empty, string.Empty);

    var serializer = new XmlSerializer(obj.GetType());

    using (var stringWriter = new StringWriter())
    {
        using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
        {
            serializer.Serialize(xmlWriter, obj, namespaces);
        }
        return stringWriter.ToString();
    }
}

并这样称呼它:

var rtnAck = new ResponseMsg
{
    Responsestatus = "00",
    CurBalance = 0.5,
    AvlBalance = 0.5,
    Acknowledgement = "1",
    LoadAmount = 0.00,
    CVV2_Result = "test"
};

var rtnData = rtnAck.ObjectToXml();

但是结果字符串是

<?xml version="1.0" encoding="utf-16"?>
<ResponseMsg>
  <Responsestatus xmlns="http://tempuri.org/">00</Responsestatus>
  <Acknowledgement xmlns="http://tempuri.org/">1</Acknowledgement>
  <CVV2_Result xmlns="http://tempuri.org/">test</CVV2_Result>
</ResponseMsg>

我设置值的其他字段在哪里?只出现了string类型,没出现的是double

此外,如何去掉每个元素上的 xmlns?

您看到以“Specified”结尾的属性了吗?这些是存在的,以便可以区分“属性存在”和“属性缺失”的情况。对于字符串属性,这由 != null== null.

隐含

因此对于 non-string 个属性,如果您希望值被序列化,您需要将 ...Specified 属性设置为 true:

var rtnAck = new ResponseMsg
{
    Responsestatus = "00",
    CurBalance = 0.5,
    CurBalanceSpecified = true,
    AvlBalance = 0.5,
    AvlBalanceSpecified = true, 
    Acknowledgement = "1",
    LoadAmount = 0.00,
    LoadAmountSpecified = true,
    CVV2_Result = "test"
};

这不是很 user-friendly,但 XmlSerialization 早于 Nullable<T>