Web Services. By now, I’m sure you’ve written some. Or at least one. If not, you should. Why? Aside from the fact that you’re a software developer and it looks really good on a resume, web services can offer a wide range of flexibility within an application’s architecture. Several years ago, I became convinced of the value a service-oriented architecture provides. You could make the argument that I was easily convinced.
You see, I’ve been a developer in a corporate world without a service-oriented architecture. Or any architecture at all, for that matter. And there are not many things in life as frustrating as having meetings upon meetings with other folks in the same company just to figure out how to share data back and forth. Never mind defining a strategy for sharing the data externally, as well. Ha! When you’re managing projects like getting data from the proprietary sales system to import into the custom-written accounting system, and constantly running into issues because of data format incompatibilities and such, you’ll soon learn to appreciate the euphoria associated with the idea of being able to provide functionality and data in a consistent manner throughout all of the business processes within an organization, regardless of custom technical requirements and implementations throughout different departments. Yes, I’ve been in an environment without a service-oriented architecture.
So when I was selected as the Lead Technical Architect for a new startup tasked with building a high transactional volume, mission-critical web application, I started by designing the services for the application’s architecture. I won’t bore you with additional arguments on the benefits of a service-oriented architecture (there’s plenty of existing material that serves that purpose), but I would like to make one final point. I’ve specifically used the term “service-oriented architecture”, not “web-service oriented architecture”. Whether you expose functionality and data via a web service, or using a different technical implementation (such as .NET Remoting) is simply a matter of semantics. The goal is the same: to provide a consistent manner in which functionality and data are made accessible to applications throughout the environment, regardless of the technical implementations of those applications. Web services allow us to share information across application and platform boundaries. With that being said, web services are not silver bullets; they do not fit every development need. For instance, if you have complete control over the client and server environments, and need better performance than a web service can provide, .NET Remoting could be the more appropriate method for communication. We’re going to focus on implementing web services since they’re based on XML and other open standards (SOAP and HTTP) and can be shared across platform boundaries, but here are some resources that compare and contrast web services with .NET Remoting:
Building, testing, and consuming a web service in Visual Studio .NET is very easy to do, and really isn’t much different from any other component programming you’ve done in the past. As a matter of fact, if you have done any component programming, you already know the drill.
First, you build the service. This service, sometimes referred to as the “provider”, encapsulates functionality and data for the given task at hand, and exposes this functionality to applications and other services, sometimes referred to as “consumers”, via an interface. This interface defines the functionality provided and all data required for processing, as well as the result of the operation.
If you’re like me, an example helps to illustrate, so let’s pick a simple one. Let’s say we’re building a Math Service. This service provides functionality for adding and subtracting integer values. Once we’ve determined the desired functionality, we can define the interface for the service, as follows:
Description: Adds two integer values
Input: FirstNumber (Integer), SecondNumber (Integer)
Example Usage: Add( 1, 1) = 2
Description: Subtracts one integer value from another
Example Usage: Subtract( 2, 1) = 1
Armed with the interface for our service, we’re ready to build it using Visual Studio.
Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
Return a + b
Public Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
Return a - b
Now the fun part of testing our service begins. I say this somewhat sarcastically, because the testing phase of component-driven development tends to be especially tedious. Typically, once we’ve built the component, the next step is to build a client application to consume all of the functionality exposed by the component (our web service, in this case). This usually represents an especially tedious process for us, since we need to test every piece of functionality within our component. Therefore, it means we’ll need to write enough UI code for our client application in order to fully test our component. Tons of controls + tons of functions = tons of time……
Luckily for us, Visual Studio .NET greatly simplifies this process for building web services. The environment automatically generates a test application for us, via a web page when we navigate to the ASMX file.
The client page rendered by navigating to the ASMX file provides a link to the WSDL file for our service. Web Services Description Language (WSDL) is an XML format used to describe how to communicate with a web service, basically describing the interface definition for the web service. With some development tools, developers are required to write the interface for a web service using WSDL. Not Visual Studio .NET. It generates the WSDL for us, based on the class definition (interface) we’ve defined. Take a moment to browse through the WSDL definition of our service, and you’ll quickly appreciate the value its generation is worth.
The client page also lists the operations provided by our web service, and allows us to drill-down into the details of each service. Let’s examine the first operation for our service.
Using this page, we can test the implementation of this operation of our web service. The page provides labels and input controls for each parameter of the operation, as well as an Invoke button that will allow us to test the operation using the HTTP POST protocol. The page also provides the format of invoking the operation using SOAP or HTTP POST, as well as sample requests and responses of each. This information can prove very valuable, especially when we need to be able to communicate with our service using certain clients. More on this in the next article. Go ahead and test the operation by providing some values.
You should see the results of the operation, in XML format. By the way, we could have stepped into the code of the operation by merely adding a breakpoint to the desired line of code within the operation. Go ahead and test out the Subtract operation in the same manner. Give the debugging a whirl to step directly into the code of your operation.
Hopefully, you have seen just how easy it is to build a web service using Visual Studio .NET. I know this is a very simple example, but I wanted to guide you through the process of building the web service and focus on the core steps involved instead of the code. We’ll look at a more practical example in the next article.
Now that we’ve written and tested a web service, let’s put it to use. In our first example, we’ll consume the service from an ASP.NET Web Application. So we’ll begin by adding a project to our solution.
Next, we need to add a web reference to our web application so we can invoke the web service.
Adding this web reference allows us to use the web service from code just like any other component in the .NET Framework. This is made possible by the automatic generation of a proxy class by Visual Studio .NET, based upon the name given to the reference. You can check out the (very interesting) implementation of this proxy class by viewing the code in Reference.vb, under the MathService tree in References. But you don’t have to. Heck, you don’t even have to know anything about this proxy class. You just write code to use the web service just like any other component! Let’s do this now.
If Not Page.IsPostBack Then
Dim ws As New MathService.Math
Label1.Text = CType(ws.Add(2, 2), String)
Label2.Text = CType(ws.Subtract(3, 1), String)
As you can see, consuming the web service from an ASP.NET web application is easy to do. Simply add a web reference to the web application project, and then we can use the web service just like any other class or component.
Now that you’re a web service guru, I’d like to make a few points. This example demonstrated the simplest way of invoking a web service from an ASP.NET web application, not necessarily the fastest way. There are ways of invoking the web service asynchronously for much better performance. I encourage you to read more on developing web services. Here are some links to get you started: