Calling service using SOAP message (.NET)

If you need to call a web service at low-level this is a good post for you.

For this purpose, you have to use HttpWebRequest and HttpWebResponse for treating the call. With Visual Studio’s auto-generated proxy for calling web methods of a web service hides the communication language between client and server. You do not have any control about the SOAP message generated. The only way is to call web methods using low-level protocol (HttpRequest)

Look an example below:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("<<Url of your web method>>");

request.Headers["SOAPAction"] = <<web method URI>>;
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Accept = "text/xml";
request.Method = "POST";

As you can see I have created the request using the information related to the web service. Next step is to build the SOAP Envelope

//Global variable for helping

static string soapEnvelope = @"<soap:Envelope xmlns:xsi='' xmlns:xsd='' xmlns:soap=''><soap:Header></soap:Header><soap:Body></soap:Body></soap:Envelope>";

StringBuilder sb = new StringBuilder(soapEnvelope);
sb.Insert(sb.ToString().IndexOf("</soap:Header>"), String.Format("<AuthorizationToken xmlns=\"<<some URI>>"><Token>{0}</Token></AuthorizationToken>", authToken.Token));
sb.Insert(sb.ToString().IndexOf("</soap:Body>"), String.Format("<YOURMethod xmlns=\"<<some URI>>"><Parameter1>{0}</Parameter1><Parameter2>{1}</Parameter2></YOURMethod>", serviceName, methodName));

XDocument soapEnvelopeXml = XDocument.Parse(sb.ToString());


And finally, make the call

IAsyncResult result = request.BeginGetRequestStream((IAsyncResult asynchronousResult) =>

//inserting soap message in the request

using (Stream postStream = request.EndGetRequestStream(asynchronousResult))

request.BeginGetResponse(new AsyncCallback(asyncresult =>
XElement res = null;
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
XDocument res = XDocument.Parse(responseString);
XNamespace ns = "<<your namespace>>";



XElement results = res.Descendants(ns + "<<your method name>>Response").FirstOrDefault();
if (results == null)
res =  results.Elements().FirstOrDefault();
}), request);
}, null);