【问题标题】:Read Soap Message using C#使用 C# 读取肥皂消息
【发布时间】:2012-08-30 16:53:37
【问题描述】:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Head>
    <h:talkId s:mustknow="1" xmlns:h="urn:schemas-test:testgate:hotel:2012-06">
      sfasfasfasfsfsf</h:talkId>
    </s:Head>
  <s:Body>
    <bookHotelResponse xmlns="urn:schemas-test:testgate:hotel:2012-06" xmlns:d="http://someURL" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <d:bookingReference>123456</d:bookingReference>
      <d:bookingStatus>successful</d:bookingStatus>
      <d:price xmlns:p="moreURL">
        <d:total>105</d:total>
      </d:price>
    </bookHotelResponse>
  </s:Body>
</s:Envelope>

我正在尝试使用 C# 阅读上述肥皂消息 XmlDocument

XmlDocument document = new XmlDocument();
document.LoadXml(soapmessage);  //loading soap message as string
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);

manager.AddNamespace("d", "http://someURL");

XmlNodeList xnList = document.SelectNodes("//bookHotelResponse", manager);
int nodes = xnList.Count;

foreach (XmlNode xn in xnList)
{
    Status = xn["d:bookingStatus"].InnerText;
}

计数始终为零,并且不读取 bookingstatus 值。

【问题讨论】:

  • 请修正格式,尤其是 XML 消息的格式(目前大部分都丢失了)。
  • xml 无效...b 是未定义的命名空间...是 d
  • @anirudha 含义,xml 样本中的 b:total 应该是 d:total
  • 并且 与 不匹配。在“id”的数量上因一个错误而关闭。

标签: c# xml soap


【解决方案1】:

BookHotelResponse 位于命名空间 urn:schemas-test:testgate:hotel:2012-06(示例 xml 中的默认命名空间)中,因此您需要在查询中提供该命名空间:

XmlDocument document = new XmlDocument(); 
document.LoadXml(soapmessage);  //loading soap message as string 
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable); 

manager.AddNamespace("d", "http://someURL"); 
manager.AddNamespace("bhr", "urn:schemas-test:testgate:hotel:2012-06"); 

XmlNodeList xnList = document.SelectNodes("//bhr:bookHotelResponse", manager); 
int nodes = xnList.Count; 

foreach (XmlNode xn in xnList) 
{ 
    Status = xn["d:bookingStatus"].InnerText; 
} 

【讨论】:

  • 在您的示例 xml 中替换了 'b:' 命名空间 id 拼写错误并将 更改为 后为我工作。您确定您的 soapmessage 中的 xml 与您示例中的格式匹配吗?
【解决方案2】:

使用LINQ2XML

要阅读 bookingStatus,请执行此操作

XElement doc = XElement.Load("yourStream.xml");
XNamespace s = "http://schemas.xmlsoap.org/soap/envelope/";//Envelop namespace s
XNamespace bhr="urn:schemas-test:testgate:hotel:2012-06";//bookHotelResponse namespace
XNamespace d="http://someURL";//d namespace

foreach (var itm in doc.Descendants(s + "Body").Descendants(bhr+"bookHotelResponse"))
{
itm.Element(d+"bookingStatus").Value;//your bookingStatus value
}

LINQ2XML 是 cool 不过....:)

【讨论】:

    【解决方案3】:

    首先您要创建一个类来将 xml 值反序列化为

        public class bookHotelResponse {
          public int bookingReference { get; set; }
          public int bookingStatus { get; set; }
       } 
    

    然后您可以利用GetElementsByTagName 提取soap 请求的主体并将请求字符串反序列化为一个对象。

        private static T DeserializeInnerSoapObject<T>(string soapResponse)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(soapResponse);
    
            var soapBody = xmlDocument.GetElementsByTagName("soap:Body")[0];
            string innerObject = soapBody.InnerXml;
    
            XmlSerializer deserializer = new XmlSerializer(typeof(T));
    
            using (StringReader reader = new StringReader(innerObject))
            {
                return (T)deserializer.Deserialize(reader);
            }
        }
    

    【讨论】:

      【解决方案4】:

      据我了解,您希望得到肥皂服务的回复。如果是这样,您不必自己完成所有这些艰苦的工作(拨打电话、解析 xml、选择节点以获取响应值)......相反,您需要将服务引用添加到您的项目中,它将完成所有剩下的工作,包括生成类,调用 asmx 等等…… 在此处阅读更多信息https://msdn.microsoft.com/en-us/library/bb628649.aspx

      添加引用后你需要做的就是调用类似这样的类方法

      var latestRates = (new GateSoapClient())?.ExchangeRatesLatest();
      return latestRates?.Rates;
      

      【讨论】:

        猜你喜欢
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 2022-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        相关资源
        最近更新 更多