客户端发送SOAP请求并收到响应
尝试创build一个将SOAP请求发送到Web服务(并获取结果)的C#客户端(将作为Windows服务开发)。
从这个问题我看到了这个代码:
protected virtual WebRequest CreateRequest(ISoapMessage soapMessage) { var wr = WebRequest.Create(soapMessage.Uri); wr.ContentType = "text/xml;charset=utf-8"; wr.ContentLength = soapMessage.ContentXml.Length; wr.Headers.Add("SOAPAction", soapMessage.SoapAction); wr.Credentials = soapMessage.Credentials; wr.Method = "POST"; wr.GetRequestStream().Write(Encoding.UTF8.GetBytes(soapMessage.ContentXml), 0, soapMessage.ContentXml.Length); return wr; } public interface ISoapMessage { string Uri { get; } string ContentXml { get; } string SoapAction { get; } ICredentials Credentials { get; } }
看起来不错,任何人都知道如何使用它,如果这是最好的做法?
不过,我通常用另一种方法来做同样的事情
using System.Xml; using System.Net; using System.IO; public static void CallWebService() { var _url = "http://xxxxxxxxx/Service1.asmx"; var _action = "http://xxxxxxxx/Service1.asmx?op=HelloWorld"; XmlDocument soapEnvelopeXml = CreateSoapEnvelope(); HttpWebRequest webRequest = CreateWebRequest(_url, _action); InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest); // begin async call to web request. IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null); // suspend this thread until call is complete. You might want to // do something usefull here like update your UI. asyncResult.AsyncWaitHandle.WaitOne(); // get the response from the completed web request. string soapResult; using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult)) { using (StreamReader rd = new StreamReader(webResponse.GetResponseStream())) { soapResult = rd.ReadToEnd(); } Console.Write(soapResult); } } private static HttpWebRequest CreateWebRequest(string url, string action) { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Headers.Add("SOAPAction", action); webRequest.ContentType = "text/xml;charset=\"utf-8\""; webRequest.Accept = "text/xml"; webRequest.Method = "POST"; return webRequest; } private static XmlDocument CreateSoapEnvelope() { XmlDocument soapEnvelopeDocument = new XmlDocument(); soapEnvelopeDocument.LoadXml(@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/1999/XMLSchema""><SOAP-ENV:Body><HelloWorld xmlns=""http://tempuri.org/"" SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""><int1 xsi:type=""xsd:integer"">12</int1><int2 xsi:type=""xsd:integer"">32</int2></HelloWorld></SOAP-ENV:Body></SOAP-ENV:Envelope>"); return soapEnvelopeDocument; } private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest) { using (Stream stream = webRequest.GetRequestStream()) { soapEnvelopeXml.Save(stream); } }
我在这里得到了这个简单的解
发送SOAP请求和接收在.NET 4.0 C#应答,而不使用WSDL或代理类:
class Program { /// <summary> /// Execute a Soap WebService call /// </summary> public static void Execute() { HttpWebRequest request = CreateWebRequest(); XmlDocument soapEnvelopeXml = new XmlDocument(); soapEnvelopeXml.LoadXml(@"<?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> <HelloWorld xmlns=""http://tempuri.org/"" /> </soap:Body> </soap:Envelope>"); using (Stream stream = request.GetRequestStream()) { soapEnvelopeXml.Save(stream); } using (WebResponse response = request.GetResponse()) { using (StreamReader rd = new StreamReader(response.GetResponseStream())) { string soapResult = rd.ReadToEnd(); Console.WriteLine(soapResult); } } } /// <summary> /// Create a soap webrequest to [Url] /// </summary> /// <returns></returns> public static HttpWebRequest CreateWebRequest() { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"http://localhost:56405/WebService1.asmx?op=HelloWorld"); webRequest.Headers.Add(@"SOAP:Action"); webRequest.ContentType = "text/xml;charset=\"utf-8\""; webRequest.Accept = "text/xml"; webRequest.Method = "POST"; return webRequest; } static void Main(string[] args) { Execute(); } }
最佳做法是引用WSDL并将其用作Web服务引用。 更容易,工作正常,但如果你没有WSDL或XSD定义是一个很好的代码。
我认为有一个更简单的方法:
public async Task<string> CreateSoapEnvelop() { string soapString = @"<?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> <HelloWorld xmlns=""http://tempuri.org/"" /> </soap:Body> </soap:Envelope>"; HttpResponseMessage response = await PostXmlRequest("your_url_here", soapString); string content = await response.Content.ReadAsStringAsync(); return content; } public static async Task<HttpResponseMessage> PostXmlRequest(string baseUrl, string xmlString) { using (var httpClient = new HttpClient()) { var httpContent = new StringContent(xmlString, Encoding.UTF8, "text/xml"); httpContent.Headers.Add("SOAPAction", "http://tempuri.org/HelloWorld"); return await httpClient.PostAsync(baseUrl, httpContent); } }
我写了一个更通用的帮助类,它接受自定义参数的基于string的字典,以便调用者可以设置它们而不必对它们进行硬编码。 不言而喻,只有在需要(或需要)手动发出基于SOAP的Web服务时,才应使用此类方法:在大多数情况下,推荐的方法是将Web Service WSDL与Add Service Reference Visual Studio一起使用function。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Xml; namespace Ryadel.Web.SOAP { /// <summary> /// Helper class to send custom SOAP requests. /// </summary> public static class SOAPHelper { /// <summary> /// Sends a custom sync SOAP request to given URL and receive a request /// </summary> /// <param name="url">The WebService endpoint URL</param> /// <param name="action">The WebService action name</param> /// <param name="parameters">A dictionary containing the parameters in a key-value fashion</param> /// <param name="soapAction">The SOAPAction value, as specified in the Web Service's WSDL (or NULL to use the url parameter)</param> /// <param name="useSOAP12">Set this to TRUE to use the SOAP v1.2 protocol, FALSE to use the SOAP v1.1 (default)</param> /// <returns>A string containing the raw Web Service response</returns> public static string SendSOAPRequest(string url, string action, Dictionary<string, string> parameters, string soapAction = null, bool useSOAP12 = false) { // Create the SOAP envelope XmlDocument soapEnvelopeXml = new XmlDocument(); var xmlStr = (useSOAP12) ? @"<?xml version=""1.0"" encoding=""utf-8""?> <soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope""> <soap12:Body> <{0} xmlns=""{1}"">{2}</{0}> </soap12:Body> </soap12:Envelope>" : @"<?xml version=""1.0"" encoding=""utf-8""?> <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> <soap:Body> <{0} xmlns=""{1}"">{2}</{0}> </soap:Body> </soap:Envelope>"; string parms = string.Join(string.Empty, parameters.Select(kv => String.Format("<{0}>{1}</{0}>", kv.Key, kv.Value)).ToArray()); var s = String.Format(xmlStr, action, new Uri(url).GetLeftPart(UriPartial.Authority) + "/", parms); soapEnvelopeXml.LoadXml(s); // Create the web request HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Headers.Add("SOAPAction", soapAction ?? url); webRequest.ContentType = (useSOAP12) ? "application/soap+xml;charset=\"utf-8\"" : "text/xml;charset=\"utf-8\""; webRequest.Accept = (useSOAP12) ? "application/soap+xml" : "text/xml"; webRequest.Method = "POST"; // Insert SOAP envelope using (Stream stream = webRequest.GetRequestStream()) { soapEnvelopeXml.Save(stream); } // Send request and retrieve result string result; using (WebResponse response = webRequest.GetResponse()) { using (StreamReader rd = new StreamReader(response.GetResponseStream())) { result = rd.ReadToEnd(); } } return result; } } }
有关此课程的其他信息和详细信息,您也可以阅读这篇文章 。