Categories
Technology

Calling Web Service without WSDL or Web Reference

Once I had to test in C# a dozen of web services developed by a third-party. However they provided no WSDL and no ASMX – therefore it would be impossible to use Web References. They only provided the name of the web methods, their urls, calling credentials and an XML request example.

  • WSDL [FAIL]: I tried to obtain an wsdl by executing Visual Studio’s wsdl.exe but I got an error saying something like "The HTML document does not contain identifying information about the Web service."
  • Service Reference [FAIL]: On Visual Studio, I tried adding a Service Reference, providing the web service’s url. I got an error downloading '<url>/_vti_bin/ListData.svc/$metadata'. Metadata contains a reference that cannot be resolved. Maybe the web service was an ASMX instead of a WCF?
  • SOAP [almost WIN]: My last hope on cleaning this mess was SOAP (pun intended). Indeed, I tried creating a class based on the code available here. Sadly, when Visual Studio executed that class on IE11 I got a rather random HTTP Error 403.14 - Forbidden, the Web server is configured to not list the contents of this directory. However I was on the right track.

After all those attempts… what is the right way, on Visual Studio, to call an external web service, without WSDL, ASMX or adding a web reference?

Solution – SOAP Messages

Turns out SOAP was really the way to go. The execution flow I used was: create a Web/SOAP request, set request method to POST (for some reason the 3rd party developed the webservices that way), convert the XML containing the WebService input into a byte array (payload), write the XML payload into the web request, use the web request to get a response from the WebService, return an XML with the WebService response (or an error XML).

I had to call WebServices with an URL pattern of:

http://www.client.com/_ws/<METHOD_NAME>?sso=<AUTHENTICATION>&o=<GET/SET/DEL>.

For example: http://www.client.com/_ws/products?sso=PASSword123&o=GET

Here is the C# code to call a WebService, through its URL, using SOAP alone:

/// <returns>ResultCode, 1 if success.</returns>
private XmlDocument CallWebService(string method, string operation, string xmlPayload)
{
    string result = "";
    string CREDENTIALS = "PASSword123";
    string URL_ADDRESS = "http://www.client.com/_ws/" + method + "?sso=" + CREDENTIALS + "&o=" + operation +;  //TODO: customize to your needs
    // ===== You shoudn't need to edit the lines below =====

    // Create the web request
    HttpWebRequest request = WebRequest.Create(new Uri(URL_ADDRESS)) as HttpWebRequest;

    // Set type to POST
    request.Method = "POST";
    request.ContentType = "application/xml";

    // Create the data we want to send
    StringBuilder data = new StringBuilder();
    data.Append(xmlPayload);
    byte[] byteData = Encoding.UTF8.GetBytes(data.ToString());      // Create a byte array of the data we want to send
    request.ContentLength = byteData.Length;                        // Set the content length in the request headers

    // Write data to request
    using (Stream postStream = request.GetRequestStream())
    {
        postStream.Write(byteData, 0, byteData.Length);
    }

    // Get response and return it
    XmlDocument xmlResult = new XmlDocument();
    try
    {
        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            result = reader.ReadToEnd();
            reader.Close();
        }
        xmlResult.LoadXml(result);
    }
    catch (Exception e)
    {
        xmlResult = CreateErrorXML(e.Message, "");  //TODO: returns an XML with the error message
    }
    return xmlResult;
}

There’s an even better way here.

6 replies on “Calling Web Service without WSDL or Web Reference”

This solution not working me please help my webservice is non soap formart and none parameter. then how can send my xml to it. above code give me 401 error.How can solve that problem.thanks in advance.

Comments are closed.