Welcome!

Microservices Expo Authors: Liz McMillan, Pat Romanski, Carmen Gonzalez, Elizabeth White, Jason Bloomberg

Related Topics: Microservices Expo

Microservices Expo: Article

Designing a Generic SOAP Client Using Visual Basic .NET

Designing a Generic SOAP Client Using Visual Basic .NET

As XML Web services invade the technology forefront,
I almost feel as if an understanding of the SOAP protocol
is becoming an everyday essential for me as a .NET developer.

Visual Studio .NET and the .NET Framework do a good job of hiding the details of low-level implementation of SOAP in Web services; however, my inner "SOAP sense" wasn't really satisfied with the little exposure to raw XML messages and SOAP protocol details I'd gotten while implementing Web services using Visual Studio .NET. So I began to implement my own SOAP Client to communicate with Web services while looking over the raw XML messages that are exchanged.

In this article I'll discuss how to build a generic SOAP Client using Visual Basic .NET. What I mean by "generic" is that this SOAP Client can be used to communicate with any Web service. I'll also discuss how to use this client to consume Web services. I chose UDDI (Universal Description, Discovery, and Integration) as a Web service to test my SOAP Client. Let's get started.

Anatomy of SOAP
SOAP is a general application-level protocol designed for application-to-application communication over any underlying transport protocol. The SOAP specification defines the XML formats for messages participating in a SOAP communication. If you have a well-formed XML document that conforms to SOAP specifications, you're ready to communicate with a Web service!

A SOAP message contains the following parts:

  • Envelope: The top-level container
    representing the message.
  • Header: An optional part of the SOAP
    message, usually used to carry data unrelated to the main application itself.
    For example, authentication information could be sent as a header in a SOAP message.
  • Body: Contains mandatory information intended for the ultimate message receiver.

In simple terms, communicating with a Web service is nothing more than formatting an XML document and sending it to the Web service server. Because the SOAP protocol is independent of the transport layer, you can implement the communication at any level, such as TCP/IP, HTTP, etc. For the purposes of this article I'm going to use HTTP as the transport layer for the SOAP communication.

Let's take a look at a sample SOAP message using HTTP, shown in Listing 1. As you can see, it looks like an HTTP-POST request. However, the main differences between a pure HTTP request and a SOAP request embedded in HTTP are the SOAP envelope payload and the SOAPAction header. With this background, let's move on to design a SOAP Client.

Designing a SOAP Client
Since I'm using HTTP as the transport layer for my SOAP Client, I need HTTP Request and Response objects for communication purposes. I'll define them in my class as shown below. (You can find these types in the namespace System.Net.)

Dim objHTTPReq As HttpWebRequest
Dim objHTTPRes As HttpWebResponse

The constructor for this class will create an instance of the HTTP Request class and bind to a specific network endpoint (the address of a Web service). So the class constructor expects a string as input, which is "Url" in the following code.

Public Sub New(ByVal Url As String)
objHTTPReq = _
CType(WebRequest.CreateDefault(New System.Uri(Url)), HttpWebRequest)
objHTTPReq.ContentType = _
"text/xml; charset=""utf-8"""
End Sub

Now that the basic class is ready, follow these steps to build a SOAP Client:

  • Set the HTTP and SOAP headers for the HTTP Request object.
  • Build the SOAP envelope around the SOAP body.
  • Attach credentials (if needed for the Web service) to the request.
  • Send the SOAP request over HTTP to the server.
  • Receive the SOAP response from the Web service.

Let's take a look at each of these steps in detail.

Set the HTTP and SOAP Headers (SetHeader)
I'm going to create a function called "SetHeader" to set various header values for the HTTP request. Even in pure HTTP communication there will be several headers associated with each HTTP request (such as "Method", "Accept", etc.). However, SetHeader will be used to set a SOAP-specific header called "SOAPAction", which is required for SOAP communication, along with the other generic HTTP headers. Since the SOAPAction header value is different for each Web service, you need to set it before communicating with any Web service.

As you can see from Listing 2, SetHeader accepts the header name and its value (name-value pairs). So when you add the SOAPAction header to your client, you need to pass both the SOAPAction literal and its value.

Build the SOAP Envelope (BuildEnv)
Now let's take a look at building the SOAP envelope and body. The SOAP body is specific to the Web service and depends on the parameters that the Web service expects, whereas the SOAP envelope is always in a standard format. BuildEnv (see Listing 3) accepts the SOAP body as a string and builds the standard SOAP envelope around it.

Attach Credentials (SetCred)
You can use SetCred (see Listing 4) from the SOAP Client class to set credentials that may be required by some Web services. For example, when you access the UDDI Publish API to publish your business/services you need to pass the credentials to invoke the Web services. In such cases SetCred comes in handy.

SetCred expects credentials (username and password) as input parameters, which it will attach to each HTTP request sent to the Web service.

Send the SOAP Request (Send)
Okay, it's time to write a function to send the actual SOAP request. The function "Send" in the SOAP Client class (see Listing 5) accepts the SOAP request message as a parameter and sends it over HTTP.

The SOAP message is simply written into the HTTP request stream using a StreamWriter class. The StreamWriter class can be found in the System.IO namespace.

Receive the SOAP Response (GetResponse)
The final step in building a SOAP Client is setting the "GetResponse" function. GetResponse is used to read the SOAP response back from the Web service. Since the response returned by the server is going to be another well-formatted XML document that conforms to the SOAP specification, I loaded the returned response into an XML DOM document to parse the SOAP body element.

The code in Listing 6 contains an interesting process. I'm trying to capture the response in the "Catch" block in case of an exception. This will help us in understanding what kind of exception occurred. I will discuss debugging SOAP applications in detail in the next section.

We've designed our SOAP Client. It's time to test it against a real Web service.

Testing the SOAP Client with a UDDI Web Service
If you're new to UDDI services, they're Web-based open directories run by various operators (such as Microsoft, IBM, etc.) that expose information about businesses, services, and related technical interfaces. By querying a UDDI service you can discover the company details and the technical details of the (Web) services they provide. For details about UDDI, you can refer to www.uddi.org. You need to format the query to the UDDI service in a prespecified XML format before sending it to the UDDI server. The specifications for these XML formats are available at www.uddi.org/pubs
ProgrammersAPI-V2.00-Open-200106 08.pdf
. Now let's say, for example, I want to query a UDDI service for a business. I need to use the "find_business" function XML format (refer to the previously mentioned API document). So if I want to find a business by the name "eSynaps", I have to format the query XML as shown below:

<find_business generic='1.0' xmlns='urn:uddi-org:api'>
<name>
esynaps
</name>
</find_business>

The above XML is going to be the SOAP body for the UDDI query. Let's move on to test the SOAP Client.

SOAPTest.ASPX
I've created a Web form, SOAPTest.ASPX (available from www.sys-con.com/ webservices/sourcec.cfm), to test the SOAP Client (see Figure 1). I hard-coded the vendors (Microsoft and IBM) into the UDDI Node dropdown list. You can choose one of the two nodes to test the SOAP Client, then select the UDDI function you want to invoke. Let's select the find_business function. Since I've already hard-coded the XML formats for all the UDDI query functions (from the UDDI API document), the XML query string format will appear in the query XML text box area of the Web form when you select a particular UDDI query function. (I've used SelectedIndexChanged event.) When you submit the form by clicking on the submit button, the "button_click" function will be executed from the code-behind page.

 

The button_click function actually instantiates the SOAP Client, sending and receiving the SOAP messages. Let's take a closer look at what's really happening in this function. First, declare the SOAP Client:

Dim objMySoap As MyComponents.MySOAPClient

Then create a new instance of the SOAP Client with the selected UDDI node from the Web form:

objMySoap = New MyComponents.MySOAPClient(node.SelectedItem.Value)

Set the HTTP and SOAP headers required to communicate with the Web service: "Method", "Accept", and "SOAPAction":

objMySoap.SetHeader("Method", "POST")
objMySoap.SetHeader("Accept", "text/xml;charset=""utf-8""")
objMySoap.SetHeader("SOAPAction", """""")

Now prepare the body of the SOAP message by building the envelope around it.

strQry = objMySoap.BuildEnv(query.Text)

Then send the XML message to the selected UDDI node using the SOAP Client's "Send" method, as shown below:

objMySoap.Send(strQry)

Receive the response from the SOAP Client by calling the GetResponse function and set it to the text area in the bottom portion of the Web form.

servOut.Text = objMySoap.GetResponse()

Now you'll see the response from the UDDI server. Figure 2 shows the XML being returned by the UDDI find_ business Web service.

 

Now let's revisit the topic of capturing the response stream from the HTTP Response object in the case of an exception. Even in case of a SOAP exception, the response stream will contain an XML message from the server with a SOAP Fault. This helps us greatly in understanding what went wrong in our communication with the Web service.

To simulate a SOAP Fault, I change the find_business query and submit the form again. The changed query and the Web service response are shown in Figure 3.

 

Changing the closing tag for the "name" element in the query XML creates an exception in the find_business Web service, causing the server to respond with a SOAP Fault message. To understand the details of the error, take a close look at the "dispositionReport". The "errInfo" element clearly states that I'm sending a malformed query XML to the Web service.

This way of capturing the response stream to read the dispositionReport in case of an exception really helps in debugging SOAP applications.

Summary
In this article you've seen how to design a SOAP Client using Visual Basic .NET and the .NET Framework. The SOAP in .NET supports only implementations over the HTTP protocol, so I chose the HTTP Request class to send the SOAP messages. You also saw the SOAP Client in action when I queried the UDDI node using the find_business Web service. You learned to set the appropriate headers to the SOAP request depending on which Web service you're going to invoke. Finally, I discussed how to debug your SOAP applications, using the disposition report from the SOAP Fault messages.

Now, since the SOAP Client is ready, you can use it against any Web service to send and receive SOAP messages to understand how the communication works and also to satisfy your "SOAP sense."

More Stories By Chandu Thota

Chandu Thota, a technical lead for ClickCommerce Inc., is coauthor of Understanding the .NET Framework, from WROX Press. Chandu is also the founder of www.eSynaps.com, an online .NET XML Web services portal.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Microservices Articles
Modern software design has fundamentally changed how we manage applications, causing many to turn to containers as the new virtual machine for resource management. As container adoption grows beyond stateless applications to stateful workloads, the need for persistent storage is foundational - something customers routinely cite as a top pain point. In his session at @DevOpsSummit at 21st Cloud Expo, Bill Borsari, Head of Systems Engineering at Datera, explored how organizations can reap the bene...
"NetApp's vision is how we help organizations manage data - delivering the right data in the right place, in the right time, to the people who need it, and doing it agnostic to what the platform is," explained Josh Atwell, Developer Advocate for NetApp, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
The Jevons Paradox suggests that when technological advances increase efficiency of a resource, it results in an overall increase in consumption. Writing on the increased use of coal as a result of technological improvements, 19th-century economist William Stanley Jevons found that these improvements led to the development of new ways to utilize coal. In his session at 19th Cloud Expo, Mark Thiele, Chief Strategy Officer for Apcera, compared the Jevons Paradox to modern-day enterprise IT, examin...
In his session at 20th Cloud Expo, Mike Johnston, an infrastructure engineer at Supergiant.io, discussed how to use Kubernetes to set up a SaaS infrastructure for your business. Mike Johnston is an infrastructure engineer at Supergiant.io with over 12 years of experience designing, deploying, and maintaining server and workstation infrastructure at all scales. He has experience with brick and mortar data centers as well as cloud providers like Digital Ocean, Amazon Web Services, and Rackspace. H...
Skeuomorphism usually means retaining existing design cues in something new that doesn’t actually need them. However, the concept of skeuomorphism can be thought of as relating more broadly to applying existing patterns to new technologies that, in fact, cry out for new approaches. In his session at DevOps Summit, Gordon Haff, Senior Cloud Strategy Marketing and Evangelism Manager at Red Hat, will discuss why containers should be paired with new architectural practices such as microservices ra...
In his session at 20th Cloud Expo, Scott Davis, CTO of Embotics, discussed how automation can provide the dynamic management required to cost-effectively deliver microservices and container solutions at scale. He also discussed how flexible automation is the key to effectively bridging and seamlessly coordinating both IT and developer needs for component orchestration across disparate clouds – an increasingly important requirement at today’s multi-cloud enterprise.
The Software Defined Data Center (SDDC), which enables organizations to seamlessly run in a hybrid cloud model (public + private cloud), is here to stay. IDC estimates that the software-defined networking market will be valued at $3.7 billion by 2016. Security is a key component and benefit of the SDDC, and offers an opportunity to build security 'from the ground up' and weave it into the environment from day one. In his session at 16th Cloud Expo, Reuven Harrison, CTO and Co-Founder of Tufin, ...
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't complete. However, applying the culture to outdated technology is a recipe for disaster; as response times grow and connections between teams are delayed by technology, the culture will die. A Nutanix Enterprise Cloud has many benefits that provide the needed base for a true DevOps paradigm. In their Day 3 Keynote at 20th Cloud Expo, Chris Brown, a Solutions Marketing Manager at Nutanix, and Mark Lav...
Many organizations are now looking to DevOps maturity models to gauge their DevOps adoption and compare their maturity to their peers. However, as enterprise organizations rush to adopt DevOps, moving past experimentation to embrace it at scale, they are in danger of falling into the trap that they have fallen into time and time again. Unfortunately, we've seen this movie before, and we know how it ends: badly.
TCP (Transmission Control Protocol) is a common and reliable transmission protocol on the Internet. TCP was introduced in the 70s by Stanford University for US Defense to establish connectivity between distributed systems to maintain a backup of defense information. At the time, TCP was introduced to communicate amongst a selected set of devices for a smaller dataset over shorter distances. As the Internet evolved, however, the number of applications and users, and the types of data accessed and...