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

使用XmlDictionaryReader反序列化指定SOAP消息的技术问询

解决SOAP多节点的反序列化问题

我来帮你搞定这个SOAP响应的反序列化!你的响应里有多个<return>节点,这是SOAP返回列表数据的常见方式,下面给你两种实用的解决方案:

方案一:使用XmlSerializer自动反序列化(推荐)

首先需要定义匹配SOAP结构的实体类,重点是处理多个<return>节点——要用[XmlElement]属性而非[XmlArray],因为这里没有包裹列表的外层节点,直接是重复的<return>元素。

定义实体类

using System.Xml.Serialization;
using System.Collections.Generic;

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

// 对应SOAP的Body节点
public class SoapBody
{
    [XmlElement(ElementName = "findContractResponse", Namespace = "http://somewebsite.com/soapService")]
    public FindContractResponse FindContractResponse { get; set; }
}

// 对应findContractResponse节点
[XmlRoot(ElementName = "findContractResponse", Namespace = "http://somewebsite.com/soapService")]
public class FindContractResponse
{
    // 用[XmlElement]标记,让序列化器识别多个同名字段为列表
    [XmlElement(ElementName = "return")]
    public List<int> ReturnValues { get; set; } // 如果是字符串就用List<string>
}

补全反序列化代码

把你的代码片段补全,用XmlSerializer解析响应流:

using (Stream rs = response.GetResponseStream())
{
    var serializer = new XmlSerializer(typeof(SoapEnvelope));
    // 反序列化得到完整的SOAP envelope对象
    var envelope = (SoapEnvelope)serializer.Deserialize(rs);
    
    // 读取所有return的值
    foreach (var contractId in envelope.Body.FindContractResponse.ReturnValues)
    {
        Console.WriteLine($"Contract ID: {contractId}"); // 会输出123和456
    }
}

方案二:手动用XDocument解析(轻量灵活)

如果不想定义实体类,也可以直接用LINQ to XML手动提取数据:

using System.Xml.Linq;

using (Stream rs = response.GetResponseStream())
{
    var doc = XDocument.Load(rs);
    
    // 声明SOAP和服务的命名空间,必须和响应里的完全一致
    XNamespace soapNs = "http://schemas.xmlsoap.org/soap/envelope/";
    XNamespace serviceNs = "http://somewebsite.com/soapService";
    
    // 链式查询找到所有return节点的值
    var returnValues = doc.Descendants(soapNs + "Body")
                          .Elements(serviceNs + "findContractResponse")
                          .Elements("return")
                          .Select(x => int.Parse(x.Value)) // 转成int,需要的话也可以保留字符串
                          .ToList();
    
    // 处理结果
    foreach (var value in returnValues)
    {
        Console.WriteLine(value);
    }
}

关键注意事项

  • 命名空间必须和SOAP响应里的完全匹配,否则会找不到目标节点
  • 如果<return>里是复杂对象,方案一的实体类可以扩展对应的属性
  • 反序列化时若遇命名空间冲突,可在XmlSerializer构造时指定额外的命名空间映射

内容的提问来源于stack exchange,提问作者Teta Chronta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:52:19