Building Distributed Apps? Use XML Web Services, Not Remoting (Mostly)
If you have been wondering whether to use XML Web services or .NET Remoting, here's a simple answer: Use XML Web services most of the time. XML Web services are the same as marshal-by-value .NET Remoting, but using them is much easier than using Remoting from scratch.
Marshal-by-value remoting (XML Web services) means that you get XML-serialized data from your remote server. Sometimes, you may need dynamic event behavior or you may not want to move massive amounts of data and need a little more control. In this instance, you peel back the XML Web services layer and start building directly on top of .NET Remoting with marshal-by-reference objects and event sinks. Mostly not, though.
This article looks at the basic technologies that support XML Web services and provides a brief demonstration of how to produce and consume Web services.
First Things First
Before learning the definition of XML Web services, take a look at Web services from a conceptual perspective. What is a Web service? I'm glad you asked.
A Web service is a class, but not a low-level class. For example, a Web service might have a method such as AddItemToOrder, BookFlight, or RetrieveDrivingDirections, but a properly used Web service would not include things like SetCustomerName or CalculateAge. A Web service could include low-level operations, but Web services send XML data across an HTTP connection and serializing data and HTTP is not a comparatively cheap operation. Therefore, using Web services to set the equivalent of property values is a misuse of them.
Conceptually, a Web service is a natural façade. The term façade is an important architectural concept that represents high-level, interface-exposing capabilities. In the context of the UML, think of a façade as a Web service that supports use cases. (If you are not familiar with façades, pick up a copy of Erich Gamma and company's book Design Patterns from Addison-Wesley.) In the meantime, think of a Web service as a place to expose high-level capabilities instead of low-level operations.
When you decide to use Web services, consider the Web service a provider of the primary use cases (a.k.a. macro features) of your system.
Consuming and Producing Web Services
A programmer can assume either the Web service producer or Web service consumer role. The skills for producing a Web service are slightly different from those for consuming Web services. When creating a Web service, you are a producer and must play that part. Once you've created the Web service, you are a consumer. The capabilities the Web service offers represent a black box, and your tasks as consumer are the same whether you produced the Web service or not.
Producing Web Services
The key to producing a useful Web service is knowing your audience. What are their objectives? What do you need from them to help them meet their goals, and what must you have from them to meet your goals?
It is also important to know that Web service consumers are generally not end users. Web services consumers are often business-to-business (b2b) customers. For example, Dell Computers might use Web services from UPS to offer package tracking. Dell Computers might produce Web services to offer financial information to Dell Financial Services. In the former scenario, Dell might ship your new PC (you're getting a Dell, dude!) via UPS and enable you to track your PC through its Web site. Dell Financial Services might offer you credit, and Dell Computers can request payment through DFS's Web services.
Hopefully, these analogies help you see what a good level of abstractioin for Web services is. Note that XML Web services do not technically enforce any particular level of abstraction; what I am suggesting is a suitable level of abstraction.
Now, how do you produce a Web service?
Producing a Web Service in VB.NET
Due in no small part to the .NET Framework, creating a Web service is no harder than creating a console application. From your perspective, you are just creating a project and adding some methods. Specific attributes defined by the .NET framework take care of adding all of the extra details you need to convert your ordinary class and assembly into a Web service. Interestingly enough, Visual Studio .NET's project templates even take care of adding the attributes necessary to distinguish regular classes and methods from Web service classes and Web methods.
To create a plain vanilla Web service, take the following steps:
- Open Visual Studio .NET.
- Select File|New|Project.
- From the New Project dialog box, select the ASP.NET Web service template and click OK.
The IDTExtensibility2 interface supports VS.NET wizards. When you open an existing project template, a pre-defined wizard reads text files that were added to your file system when you installed VS.NET. These text files contain replaceable parameters, which are filled in to create project elements such as configuration files and source code files with attributes for XML Web services.
The previously defined steps employ these template files and wizard to create a Web service project. If you uncomment the four lines of code included in the project template, you already have a complete Web service, albeit a do-nothing Hello World-style Web service.
Uncomment the code shown in Listing 1 and select Debug|Start to run the Web service. For now, ignore all of the code except what is in boldface near the end of the listing.
Listing 1: The basic sample Web service included with VS.NET's template Web service is our friend HelloWorld.
Imports System.Web.Services <System.Web.Services.WebService(Namespace := _ "http://tempuri.org/WebService1/Service1")> _ Public Class Service1 Inherits System.Web.Services.WebService #Region " Web services Designer Generated Code " Public Sub New() MyBase.New() 'This call is required by the Web services Designer. InitializeComponent() 'Add your own initialization code after the 'InitializeComponent() call End Sub 'Required by the Web services Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Web 'services Designer 'It can be modified using the Web services Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container() End Sub Protected Overloads Overrides Sub Dispose(ByVal disposing _ As Boolean) 'CODEGEN: This procedure is required by the Web services 'Designer 'Do not modify it using the code editor. If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub #End Region ' WEB SERVICE EXAMPLE ' The HelloWorld() example service returns the string Hello ' World. ' To build, uncomment the following lines; then save and build ' the project. ' To test this Web service, ensure that the .asmx file is the ' start page and press F5. ' <WebMethod()> _ Public Function HelloWorld() As String Return "Hello World" End Function End Class