calling WCF services using SOAP

21,876

@John Saunders is correct in his comment. Whatever you do with ASMX, you should be able to do with WCF. In fact it does not matter what kind of framework/technology your web service uses as long as you do a proper SOAP request.

WCF is just a framework that helps build service-oriented applications. Like any other framework of that kind, it lets you concentrate on the actual service that you will provide, taking care of all the plumbing functionality needed to expose that service as a SOAP web service.

As for SoapUI, its a Java tool that allows you to test web services. When you feed it a WSDL, it dynamically creates request samples which are then sent to the web service with (if I'm not mistaken) Http Client.

Nothing fancy happens if you have a WCF web service. It's still SOAP communication that you can do even with a basic client like this:

public class Program
{
    public static void Main(string[] args)
    {
        // OK, this is not a WCF web service, but that should not matter :D
        string endpoint = "http://www.html2xml.nl/Services/Calculator/Version1/Calculator.asmx";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endpoint);
        request.ContentType = "text/xml"; // or application/soap+xml for SOAP 1.2
        request.Method = "POST";
        request.KeepAlive = false;

        //In case you have a proxy to resolve the server name also add these lines
        var proxyServer = new WebProxy("XX.XX.XX.XX", 1234);
        proxyServer.Credentials = CredentialCache.DefaultCredentials; // or username + password
        request.Proxy = proxyServer;

        // you can read these from files
        string payload = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:tem=""http://tempuri.org/"">
                               <soapenv:Header/>
                               <soapenv:Body>
                                  <tem:Add>
                                     <tem:a>1</tem:a>
                                     <tem:b>2</tem:b>
                                  </tem:Add>
                               </soapenv:Body>
                            </soapenv:Envelope>";

        byte[] byteArray = Encoding.UTF8.GetBytes(payload);
        request.ContentLength = byteArray.Length;

        Stream requestStream = request.GetRequestStream();
        requestStream.Write(byteArray, 0, byteArray.Length);
        requestStream.Close();

        HttpWebResponse response = null;
        try
        {
             response = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException ex)
        {
             response = (HttpWebResponse)ex.Response;
        }

        Console.WriteLine(string.Format("HTTP/{0} {1} {2}\n", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription));

        // you can write this to files
        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);
        Console.WriteLine(reader.ReadToEnd());

        // cleanp
        reader.Close();
        requestStream.Close();
        responseStream.Close();
        response.Close();
    }
}

You get back a SOAP response, in this case this:

HTTP/1.1 200 OK

<?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>
        <AddResponse xmlns="http://tempuri.org/">
            <AddResult>3</AddResult>
        </AddResponse>
    </soap:Body>
</soap:Envelope>

and it does not matter if it was an ASMX that generated it, or WCF or whatever. It's the response to a HTTP request.

If instead you send an invalid message, like:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:Add>
         <tem:a>x</tem:a>
         <tem:b>y</tem:b>
      </tem:Add>
   </soapenv:Body>
</soapenv:Envelope>

you will get back a fault, something like:

HTTP/1.1 500 Internal Server Error

<?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>
        <soap:Fault>
            <faultcode>soap:Client</faultcode>
            <faultstring> ... exception stacktrace here ... </faultstring>
            <detail />
        </soap:Fault>
    </soap:Body>
</soap:Envelope>

You can automate the tests with SoapUI or even integrate them with Junit, you could even use something like JMeter which although not designed specially for web services (like SoapUI) it can test SOAP. And you can off course use that basic client I added to my answer.

Share:
21,876
s mac
Author by

s mac

Updated on July 09, 2022

Comments

  • s mac
    s mac almost 2 years

    I'm trying to test a WCF service without creating a WCF client. I have similar code/issues as presented here.

    I want full control on the SOAP payload so I want to be able to issue my own web requests/responses and substitute my own XML as the parameters into any method. I also want the return SOAP XML exactly as is, without creating response objects, fault exception objects, etc.

    As a point of reference, I want to do exactly what SoapUI is doing at the point you click the execute button and get the response back. I'm only assuming that SoapUI is NOT creating a WCF client, building the request and calling the method, but rather issuing a full SOAP call to the WCF service and displaying the result.

    In answer to the questions in the comments, the reason I don't want to create a WCF client is that I want to be insulated from any and all changes to the service, not have to rebuild references, modify my own code, create separate code for every new service/method, etc. because this process is kicked off automatically after every build, with no interaction.

    So, I have hundreds of thousands of test XML parameters that I pass into hundreds of methods, without caring about what they are. We have done it for years on ASMX web services and the one method (very similar to the above link) handled all web services/methods/test parameters.

    With switching to WCF I get internal server errors especially when testing invalid XML nodes: missing required nodes, errors in a create method for duplicate names, etc. (any error condition). I think it makes sense that there is an easy way to do this with WCF in the same manner.

    I want EXACTLY what SoapUI is sending back, I just need to know how it's doing it.