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
相关产品推荐
相关产品推荐

