You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core城市API XML响应反序列化失败问题排查

问题:SOAP XML反序列化时NewDataSet为null,无法获取RetailCities数据

调用城市API返回XML格式响应,反序列化时可获取到diffgram对象,但其中的NewDataSet属性为null,无法获取RetailCities列表。已创建带有XmlElement注解的模型类,相关内容如下:

API响应

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soap:Body>
          <getRTLCitiesResponse xmlns="http://track.smsaexpress.com/secom/">
             <getRTLCitiesResult>
                <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
                   <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                      <xs:complexType>
                         <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="RetailCities">
                               <xs:complexType>
                                  <xs:sequence>
                                     <xs:element name="routCode" type="xs:string" minOccurs="0" />
                                     <xs:element name="rCity" type="xs:string" minOccurs="0" />
                                  </xs:sequence>
                               </xs:complexType>
                            </xs:element>
                         </xs:choice>
                      </xs:complexType>
                   </xs:element>
                </xs:schema>
                <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                   <NewDataSet xmlns="">
                      <RetailCities diffgr:id="RetailCities1" msdata:rowOrder="0">
                         <routCode>ABT</routCode>
                         <rCity>Aqiq</rCity>
                      </RetailCities>
                      <RetailCities diffgr:id="RetailCities2" msdata:rowOrder="1">
                         <routCode>ABT</routCode>
                         <rCity>Atawlah</rCity>
                      </RetailCities>
                      <RetailCities diffgr:id="RetailCities3" msdata:rowOrder="2">
                         <routCode>ABT</routCode>
                         <rCity>Baha</rCity>
                      </RetailCities>
                   </NewDataSet>
                </diffgr:diffgram>
             </getRTLCitiesResult>
          </getRTLCitiesResponse>
       </soap:Body>
</soap:Envelope>

模型类与反序列化代码

[XmlRoot(ElementName = "RetailCities")]
public class RetailCity
{
    [XmlElement(ElementName = "routCode")]
    public string RoutCode { get; set; }

    [XmlElement(ElementName = "rCity")]
    public string RCity { get; set; }
}

[XmlRoot(ElementName = "NewDataSet")]
public class NewDataSet
{
    [XmlElement(ElementName = "RetailCities")]
    public List<RetailCity> RetailCities { get; set; } = new List<RetailCity>();
}

[XmlRoot(ElementName = "diffgram", Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1")]
public class Diffgram
{
    [XmlElement(ElementName = "NewDataSet")]
    public NewDataSet NewDataSet { get; set; }
}

[XmlRoot(ElementName = "getRTLCitiesResult", Namespace = "http://track.smsaexpress.com/secom/")]
public class GetRTLCitiesResult
{
    [XmlElement(ElementName = "diffgram", Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1")]
    public Diffgram Diffgram { get; set; }
}

[XmlRoot(ElementName = "getRTLCitiesResponse", Namespace = "http://track.smsaexpress.com/secom/")]
public class GetRTLCitiesResponse
{
    [XmlElement(ElementName = "getRTLCitiesResult")]
    public GetRTLCitiesResult GetRTLCitiesResult { get; set; }
}

[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class SoapBody
{
    [XmlElement(ElementName = "getRTLCitiesResponse", Namespace = "http://track.smsaexpress.com/secom/")]
    public GetRTLCitiesResponse GetRTLCitiesResponse { get; set; }
}

[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class SoapEnvelope
{
    [XmlElement(ElementName = "Body")]
    public SoapBody Body { get; set; }

    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces Xmlns { get; set; } = new XmlSerializerNamespaces();

    public SoapEnvelope()
    {
        Xmlns.Add("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        Xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        Xmlns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
    }
}

private static T DeserializeXml<T>(string xml)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    using (StringReader reader = new StringReader(xml))
    {
        return (T)serializer.Deserialize(reader)!;
    }
}

API调用代码

using (var client = new HttpClient())
{
    var content = new StringContent(AramexCitiesSoapEnvelope(), Encoding.UTF8, "text/xml");

    try
    {
        var response = await client.PostAsync(endPoint, content);

        if (response.IsSuccessStatusCode)
        {
            // Read and return the response content
            var resultContent = await response.Content.ReadAsStringAsync();                 
            var envelope = DeserializeXml<SoapEnvelope>(resultContent);

            return envelope;
        }
        else
        {
            // Return the failed response content
            var errorContent = await response.Content.ReadAsStringAsync();
            return new SoapEnvelope() { ErrorMessage = errorContent };
        }
    }
    catch (HttpRequestException e)
    {
        return new SoapEnvelope() { ErrorMessage = e.Message };
    }
}

问题原因

XML中的NewDataSet元素明确声明了xmlns=""(空默认命名空间),但当前Diffgram类中NewDataSet属性的XmlElement注解未指定对应的空命名空间,导致XmlSerializer无法匹配该元素,最终赋值为null。

修复方案

修改Diffgram类的NewDataSet属性注解,添加空命名空间声明:

[XmlRoot(ElementName = "diffgram", Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1")]
public class Diffgram
{
    [XmlElement(ElementName = "NewDataSet", Namespace = "")] // 新增空命名空间匹配
    public NewDataSet NewDataSet { get; set; }
}

额外补充:GetRTLCitiesResult中包含未处理的<xs:schema>元素,虽然不影响数据获取,但会触发XmlSerializer警告,可添加属性忽略或处理:

[XmlRoot(ElementName = "getRTLCitiesResult", Namespace = "http://track.smsaexpress.com/secom/")]
public class GetRTLCitiesResult
{
    [XmlElement(ElementName = "diffgram", Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1")]
    public Diffgram Diffgram { get; set; }

    // 忽略schema元素,避免警告
    [XmlElement(ElementName = "schema", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public XmlNode Schema { get; set; }
}

修改完成后,反序列化即可正确获取NewDataSet及下属的RetailCities列表数据。


内容的提问来源于stack exchange,提问作者Faisal Shahab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:14:58