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

C#如何从WSDL生成XML请求?HTTP调用WSDL服务需求

嘿,我来帮你搞定这个计算器Web服务的XML请求生成事儿!先看你给的WSDL片段,Add方法需要两个int类型的参数intA和intB,目标命名空间是http://tempuri.org/。下面给你几种C#实现的方式,按需选就行:

方法1:手动拼接XML字符串(简单直接)

如果请求结构比较简单,直接拼接字符串是最快速的方式,注意要保证命名空间和参数格式正确:

public string GenerateAddRequestXml(int intA, int intB)
{
    return $@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
               xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" 
               xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
  <soap:Body>
    <Add xmlns=""http://tempuri.org/"">
      <intA>{intA}</intA>
      <intB>{intB}</intB>
    </Add>
  </soap:Body>
</soap:Envelope>";
}

这里要注意:soap命名空间是SOAP 1.1的标准命名空间,如果你的服务用的是SOAP 1.2,要改成http://www.w3.org/2003/05/soap-envelope。

方法2:用XmlSerializer序列化实体类(健壮规范)

如果请求结构复杂,或者后续可能有变更,用实体类序列化的方式更靠谱,不容易出错。先定义和WSDL对应的实体:

using System.Xml.Serialization;

// 对应WSDL中的Add请求元素
[XmlRoot("Add", Namespace = "http://tempuri.org/")]
public class AddRequest
{
    [XmlElement("intA")]
    public int IntA { get; set; }

    [XmlElement("intB")]
    public int IntB { get; set; }
}

// 包装SOAP信封的通用类
[XmlRoot("Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class SoapEnvelope<T>
{
    [XmlElement("Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public SoapBody<T> Body { get; set; }

    public SoapEnvelope()
    {
        Body = new SoapBody<T>();
    }
}

public class SoapBody<T>
{
    [XmlElement(typeof(T))]
    public T Content { get; set; }
}

然后写生成XML的方法:

public string GenerateAddRequestXmlWithSerializer(int intA, int intB)
{
    var addRequest = new AddRequest { IntA = intA, IntB = intB };
    var soapEnvelope = new SoapEnvelope<AddRequest> { Body = { Content = addRequest } };

    var serializer = new XmlSerializer(typeof(SoapEnvelope<AddRequest>));
    using var stringWriter = new StringWriter();
    serializer.Serialize(stringWriter, soapEnvelope);
    return stringWriter.ToString();
}

这种方式的好处是,只要实体类和WSDL定义一致,生成的XML肯定符合要求,后续修改参数也只需要调整实体类。

完整示例:生成并发送HTTP请求

如果你需要直接把请求发送到Web服务,这里给你一个用HttpClient调用的完整示例:

using System.Net.Http;
using System.Text;
using System.Xml;

public async Task<int> CallAddWebService(int intA, int intB, string serviceUrl)
{
    // 生成XML请求(用上面任意一种方法都可以)
    var requestXml = GenerateAddRequestXml(intA, intB);

    using var httpClient = new HttpClient();
    // 注意SOAPAction头必须和服务要求一致,一般是命名空间+方法名
    httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://tempuri.org/Add");
    
    var content = new StringContent(requestXml, Encoding.UTF8, "text/xml");
    var response = await httpClient.PostAsync(serviceUrl, content);
    
    // 确保请求成功
    response.EnsureSuccessStatusCode();
    
    // 解析响应(这里假设响应结构是<AddResponse><AddResult>...</AddResult></AddResponse>)
    var responseXml = await response.Content.ReadAsStringAsync();
    var doc = new XmlDocument();
    doc.LoadXml(responseXml);
    var resultNode = doc.SelectSingleNode("//*[local-name()='AddResult']");
    return int.Parse(resultNode.InnerText);
}

几个关键注意点

  • 确认SOAPAction请求头的正确性,大部分SOAP服务都要求这个头,值一般是目标命名空间/方法名
  • 所有XML元素的命名空间必须和WSDL中的targetNamespace完全一致,不然服务会无法识别请求
  • 如果是SOAP 1.2协议,除了修改soap命名空间,还要把Content-Type改成application/soap+xml,而不是text/xml

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:59:08