5

I require developing a .NET 4.5 Client for a SOAP based web service. The problem is the company who are developing these SOAP based services do not provide WSDLs. However they do provide the request response schemas (XSD files). Since there are no WSDLs I'm unable to add a web reference and get the client proxy code autogenerated.

Are there any .NET 4.5 libraries out there that I can use to make these SOAP base service calls? It needs to support SOAP 1.1 and SOAP attachements too.

Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
Harindaka
  • 4,658
  • 8
  • 43
  • 62
  • One options would be to use WCF and use the "channel layer". You'll still need the interfaces of the WebService you want to use. – Marvin Smit Oct 28 '14 at 07:44
  • 1
    ...or just create the WSDL on your own and use that to "add the web-reference". – Christoph Fink Oct 28 '14 at 07:45
  • Creating the WSDL would be the good idea in your case as it will save your hours against dealing with serializable entities. Also this approach will be secure for service as well if they have configured message level security. – tom Oct 28 '14 at 09:27

1 Answers1

10

If for some reason you don't want to create the WSDL file, the example below could be used to manually construct a SOAP HTTP request:

var url = Settings.Default.URL; //'Web service URL'
var action = Settings.Default.SOAPAction; //the SOAP method/action name

var soapEnvelopeXml = CreateSoapEnvelope();
var soapRequest = CreateSoapRequest(url, action);
InsertSoapEnvelopeIntoSoapRequest(soapEnvelopeXml, soapRequest);

using (var stringWriter = new StringWriter())
{
    using (var xmlWriter = XmlWriter.Create(stringWriter))
    {
        soapEnvelopeXml.WriteTo(xmlWriter);
        xmlWriter.Flush();
    }
}

// begin async call to web request.
var asyncResult = soapRequest.BeginGetResponse(null, null);

// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
var success = asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5));

if (!success) return null;

// get the response from the completed web request.
using (var webResponse = soapRequest.EndGetResponse(asyncResult))
{
    string soapResult;
    var responseStream = webResponse.GetResponseStream();
    if (responseStream == null)
    {
        return null;
    }
    using (var reader = new StreamReader(responseStream))
    {
        soapResult = reader.ReadToEnd();
    }
    return soapResult;
}

private static HttpWebRequest CreateSoapRequest(string url, string action)
{
    var 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()
{
    var soapEnvelope = new XmlDocument();
    soapEnvelope.LoadXml(Settings.Default.SOAPEnvelope); //the SOAP envelope to send
    return soapEnvelope;
}

private static void InsertSoapEnvelopeIntoSoapRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
    using (Stream stream = webRequest.GetRequestStream())
    {
        soapEnvelopeXml.Save(stream);
    }
}
Matt Ko
  • 969
  • 7
  • 14
  • Thanks you so much Matt. Guess I'll build on this and see how I can incorporate SOAP attachements in the request also. Thanks a lot. – Harindaka Oct 30 '14 at 07:01
  • i have mistake .[hear](http://stackoverflow.com/questions/36998808/call-service-with-url-mistake).may help me? – shahroz May 03 '16 at 08:12
  • I was shaking my head for ages at this, getting a 500 Internal Server Error (`Server did not recognize the value of HTTP Header SOAPAction: MyWebMethod`) - I finally figured out that you need to add the namespace as specified by the service, e.g. `http://tempuri.org/MyWebMethod` as the `action` parameter! – komodosp Apr 25 '19 at 10:58
  • i'm using this example on my project, but i can't get HTTP Status code. How do i get HTTP Status code from this? – Sambuu Sep 01 '21 at 05:39