The Book of VB .NET: .NET Insight for VB Developers
Author: Matthew MacDonald
Built on the Microsoft .NET framework, Visual Basic .NET allows programmers to create everything from full-featured Internet applications to sophisticated Windows programs with the latest eye-catching interfaces. This comprehensive guide is organized into a series of lightning tours and real-world examples, covering web development, XML, databases, and user interface design. Each chapter begins with an overview of changes from Visual Basic 6. The book also includes extra code examples, references to additional online material, and helpful tips about planning, design, and architecture.
Read Chapter 13: Web Services from this book.
ISBN: 1886411824 Buy this book now!
Excerpted with permission from The Book of VB .NET, by Matthew MacDonald, No Starch Press, Copyright 2002.
|
WEB SERVICES
Web Services are a new introduction to Visual Basic .NET, and are being touted by Microsoft as a new and revolutionary way to program with the Internet. All this excitement raises the inevitable question: Are Web Services really the future of programming, and a sound career investment, or are they doomed to become the "next great thing" that wasn't?
A little background on the subject should help us find the answers. First of all, the concept of Web Services hasn't been created by Microsoft. It represents an exciting new area that several companies are clamoring to gain control of, including such heavyweights as Sun Microsystems and IBM. However, Microsoft has been planning their implementation of Web Services for quite a while, and it shows. Microsoft has made Web Services incredibly easy to program in .NET, while retaining the ability to let Web Services work seamlessly across different browsers and operating systems. A great deal of thought has gone into Web Services, and there is good reason to believe that they are destined to become another powerful tool in the advanced programmer's arsenal, along with ActiveX, COM, and other revolutionary technologies from the past.
This article starts by asking "What is a Web Service?" and takes you through the process of creating, deploying, and interacting with one. Luckily, .NET makes Web Services so quick and convenient that you can be creating simple examples in no time at all. However, it may take many more months of experimentation before you start to realize all of the possible ways Web Services can be used. The end of this article includes some helpful web links to live examples of Web Services.
New in .NET
Web Services are making their debut in Visual Studio .NET-they haven't existed in any form before. Some developers may have created custom Web Service implementations using Microsoft's SOAP toolkit, but only for highly specialized applications.
In fact, Web Services are so new and so promising that they are sometimes identified synonymously with the entire .NET platform. Of course, now that you have read Chapter 1 of The Book of VB .NET, you know what .NET is really about. How large a part Web Services will play in Microsoft's strategy of integrating languages, embracing open standards, and programming the Internet remains to be seen.
The Vision of the Interactive Web
What is a Web Service anyway? Clearly, many sites on the Internet provide useful "services." A common example is a shipping company, which allows you to look up the location and delivery date of packages using a tracking number. Is this a Web Service?
The delivery date lookup meets one of the criteria of a Web Service-it's a discrete unit of functionality that serves a single purpose: returning information about your package. But in order to get this information, you have to navigate to the correct HTML page, select an option from a menu, and then enter your tracking number. In other words, you have to use an Internet application- represented by the shipping company's website-in order to get the information you need.
Web Services: COM for the Internet?
One of the great developments in Windows programming was COM (some parts of which are also called ActiveX), a technology that allows code components to be easily shared among applications. When COM was introduced, it added flexibility.
Instead of using monolithic applications, custom utilities could be created that reused a subset of all the capabilities provided in COM components. In this respect, Web Services are like COM for the Internet. With a Web Service, you can take a unit of logic in a web application, and allow it to be seamlessly accessed and used by other Windows or Internet applications, in a variety of different ways. A Web Service is like a business object: It accepts information and returns information. Your program uses Web Services, without needing to involve the user, and takes care of providing the appropriate user interface. This is particularly important in the world of the Internet, where a user might be accessing information from a full-featured Internet Explorer browser, or from a stripped down interface on a cell phone or other wireless device. In this case, the Web Service used would be the same, but a different application would take care of the display. Like a COM object, a Web Service doesn't need to be tied to any specific interface.
In one important way, however, Web Services are not like COM technology. COM relies on a proprietary Windows standard, which means that it's useless for Macintosh computers, UNIX systems, or any other non-Microsoft platform. Web Services, however, are built on open standards such as SOAP, XML, and WSDL, which will be described in this article. This means that any application can interact with them (though none so easily as a .NET application), and that they can transmit data painlessly over HTTP. Because data is exchanged in a text XML format, there's also no problem sending a Web Service request or receiving its response, even when the Web Service is behind a corporate firewall.
Web Services Today
You are probably already making use of "first generation" Web Services. These are examples of Internet procedures that are integrated into desktop programs, but require company-specific and site-specific standards. For example, you may use a personal finance desktop application that can automatically retrieve stock portfolio information from the Internet. This type of application retrieves information from the Internet, and doesn't bother you with the details of the process. However, it relies on having information provided in a specific way, which was been planned and set up in advance, according to the particular application. It does not use an independent, widely accepted standard, as Web Services will with .NET. As a consequence, other applications can't easily extend or work with its functions and features. They must be recreated for every application that require them.
Now imagine a world with thousands of Web Service components, where a desktop application has access to all kind of features that require up-to-theminute information from the Web. In all likelihood, everyone will have some type of "always on" broadband Internet access, and you won't even be aware when your application is interacting with the Web. Programmers will no longer have to try and constantly redesign off-the-cuff solutions that schedule Internet downloads or parse HTML files manually, looking for specific information.
Of course, that's the future. Today, Web Services will allow you to further modularize Internet applications, and provide components that can be consumed and reused by any other application. Web Services can also use authentication and login procedures, allowing you to support various subscription models. In other words, you can sell units of application functionality to other developers, just like programmers sell ActiveX controls today.
Are Web Services Objects?
Web Services are not objects, at least not in the traditional sense of the word. The main distinction is that Web Services don't maintain state, unless you specifically take extra steps to store information in a database or ASP.NET's Session state collection. In fact, a Web Service that maintains state is rarely a good idea because it means the web server must allocate a portion of its precious memory for each client, which can quickly impose a noticeable performance penalty as the number of clients increases.
Web Services also don't support object-oriented basics like overloaded functions and property procedures. Constructors work, but the Web Service class is destroyed and reconstructed with each request, even if the client maintains a reference. This makes sure that Web Services perform well, but it also means that they can't be used like a local business object. It's best to think of a Web Service as a utility class made up of shared members. You can call a remote function to get a piece of information, but you shouldn't expect to keep a Web Service around and store information in it.
Creating Your First Web Service
Creating a Web Service is easier than you might think. All you have to do is create a class that incorporates some useful functions. This class should inherit from the System.Web.Services.WebService class (for maximum convenience), and all the methods that are going to be made available over the Web must be marked with attributes.
To start creating this application, begin a new project and choose ASP.NET Web Service. A series of support files will be created, as with an ASP.NET application. The actual Web Service is contained in the .asmx file (named Service1.asmx by default). The design view of the .asmx file isn't used, but the code view will start off with a couple of sample lines needed to define the Web Service class.
NOTE A Web Service, like the ASP.NET applications we saw in the previous chapter of The Book of VB .NET, must be hosted on a web ser ver in a virtual directory. The Web Service examples for this article are contained in the NoStarchWeb virtual directory. Web Service clients, on the other hand, can be located in any directory.
Now consider a very rudimentary example of a Web Service class for providing information about a package tracked with a shipping company:
Imports System.Web.Services
Public Class PostalWebService
Inherits System.Web.Services.WebService
<WebMethod> Public Function GetDeliveryDate(ByVal TrackID As String) As Date
Dim PackageInfo As Package
PackageInfo = GetPackageRecordFromDB(TrackID)
Return PackageInfo.Date
End Function
Private Function GetPackageRecordFromDB(ByVal TrackID As String) As Package
' Some database access code here.
End Function
End Class
Public Class Package
Public PackageID As String
Public DeliveryDate As Date
End Class
The Package class encapsulates information about a package. Notice that it doesn't inherit from WebService class or use the attribute because it isn't a Web Service. Instead, it is used internally in the PostalWebService class, to pass information.
The PostalWebService class has two functions. The GetDeliveryDate function is marked with a special attribute, , which indicates that it will be provided in the public interface of the Web Service. No other functions are available. GetPackageRecordFromDB is used internally by your code to get information, but it is not made available to any clients.
Now, believe it or not, any application using this Web Service will have access to the features and operations of the GetDeliveryDate function. All you need is a class that inherits from the basic WebService class, and uses the attribute. Could it be any easier? Touching Up Your Web Service
To improve your Web Service, you might want to add a description to the attribute. This description may be displayed for the client developing the application that will use your Web Service, depending on the type of development tool they are using.
<WEBMETHOD(DESCRIPTION:="USE THIS FUNCTION TO...")>
You should also specify a namespace for your Web Service. Ideally, your namespace should be uniquely identified with you-your company name, for example, or best of all, your web address. If you do not specify a namespace, the default (http://tempuri.org/) will be used. Be aware that this is an XML namespace, not a .NET namespace. An XML namespace looks like an URL, but it doesn't need to correspond to a valid Internet location (although it often does). XML namespaces are just used to distinguish portions of an XML document.
To specify a namespace, change the first line of your class declaration to use the WebService attribute:
<WEBSERVICE(NAMESPACE:="HTTP://MYCOMPANY.COM/POST")> _
Public Class PostalWebService
Enhancing the PostalWebService class
You can also make a more useful Web Service that returns a custom object with several pieces of information at once, as shown in the following example. Notice that the Package information has been separated into two classes; we'll assume here that you will not want to provide the entire database record to the client, in case it includes sensitive information (such as a credit card number).
Public Class PostalWebService
Inherits System.Web.Services.WebService
<WEBMETHOD> Public Function GetPackageInfo(ByVal TrackID As String) _
As ClientPackageInfo
Dim PackageInfo As Package
PackageInfo = GetPackageRecordFromDB(TrackID)
Return PackageInfo.BasicInfo
End Function
Private Function GetPackageRecordFromDB(ByVal TrackID As String) As Package
' Some database access code here.
Dim PackageInfo As New Package()
' To perform a crude test, uncomment the following two lines.
' PackageInfo.BasicInfo.PackageID = TrackID
' PackageInfo.BasicInfo.DeliveryDate = Now
Return PackageInfo
End Function
End Class
Public Class Package
Public BasicInfo As New ClientPackageInfo
Public CreditCardNumber As String
End Class
Public Class ClientPackageInfo
Public PackageID As String
Public DeliveryDate As Date
End Class
Database and OOP mavens will realize that there are many different ways to implement this type of scenario. (You may also wonder why the credit card is stored with each package.) In a real world example, security concerns will shape the whole construction of the database.
In any case, this example demonstrates that a .NET Web Service can pass many types of information to the client, including DataSets, .NET objects, arrays, and simple variables. Keep in mind, however, that if you were to pass an object with a built-in method, the method would be lost. Only the data is preserved.
Testing Your Web Service
So now that you have created a Web Service, how can you use it? Or maybe you're still wondering exactly what is provided with the Web Service we've created. Fortunately, Internet Explorer includes a handy feature that allows you to preview and perform a limited test on any Web Service. Your Web Service in Action
To try out this useful feature, run your Web Service. Remember, Web Services are designed to be used from inside other applications, not executed directly. However, when you choose to run a Web Service in Visual Studio .NET, your browser will display the test page shown in Figure 13-1.
This window lists all the available Web Service methods. (In this case, only one, GetPackageInfo, is available.) The Service Descriptions link will display the WSDL description of your Web Service. (WSDL is described in the next section of this article.)
Figure 13-1: The Internet Explorer test page
Click on the GetPackageInfo link, and the following test page will appear:
Ignore the puzzling XML code at the bottom of the page for now, and concentrate on the first portion of the page, which provides a prefabricated way for you to test your application. Try it by entering a package ID and clicking on Invoke. If you've entered the preceding example, and uncommented the hardcoded package values, you will receive the result shown in Figure 13- 3.
Figure 13-2: Testing a Web Service method
Figure 13- 3: AWeb Service response
At this point you'll probably start to wonder if your Web Service has worked at all. However, on close examination, it turns out that the appropriate information is present; it's just been marked up in a special XML format. What you have received is a translated version of the ClientPackageInfo class. The class is marked with a beginning and an ending tag, and inside are the members, including a PackageID and a DeliveryDate field.
You don't need to understand the format of this information if you are programming in Visual Basic .NET. As you'll discover later in this article, .NET provides special utilities that abstract away this layer of XML. These features allow you to call a Web Service and retrieve its data as thought it were a local function inside your application. However, understanding this format can give you some additional insight into what's really going on with Web Services.
The Open Standards Plumbing
Much of the excitement over Web Services results from the fact that they are built on open standards. It's this foundation that makes them more flexible and extensible than previous attempts at allowing distributed component-based programming, including such existing standards as DCOM (Microsoft's own Distributed COM), and RMI (Java's Remote Method Invocation).
XML and WSDL
Web Services use remote function calls written in XML language. XML language is ideally suited to Web Services because it is text-based, which means that unlike binary data, for instance, it can easily flow over normal HTTP channels on the Internet without getting stopped by corporate firewalls. XML is also excellent because it is self-describing, and it provides a way to identify (or "mark up") information.
XML, however, is only the starting point. XML is just a tool for describing data, much as SQL is a tool for accessing databases. Both are generic, and both can be used in countless different ways. What is needed is an agreed-upon standard for encoding information in XML, guaranteeing that other clients will be able to decode the information by following a uniform set of rules.
The standard way of describing your .NET Web Services is WSDL, an XMLbased language that has been accepted by Microsoft, IBM, and a host of other vendors. If you want to find out all the low-level details of WSDL, you can read up on it at http://msdn.microsoft.com/xml/general/wsdl.asp. However, for most developers, these details won't hold any more interest than the kinds of technology that underlie many of the other aspects of the .NET platform. What is more interesting is examining the WSDL information that Visual Basic .NET generates automatically for your particular Web Service. To display this information, click on the Service Description link on the Internet Explorer Web Service test page. You'll see a lengthy-and perhaps intimidating-document that describes the types and the functions used in your Web Service.
A portion of the WSDL document for the PostalWebService is shown in Figure 13- 4 .
Figure 13- 4: Part of the WSDL document describing a Web Service
SOAP
WSDL describes your Web Service, but another standard is needed to communicate with it. In fact, there are three different ways to communicate with a Web Service. The first is HTTP GET, which Internet Explorer uses automatically when you click on Invoke on your test page. The second is HTTP POST, which is very similar to HTTP GET. Internet veterans will realize that a POST request sends information in the body of an HTTP request instead of in the query string. The final method is SOAP, which is what .NET will use transparently when you create a client later in this article.
SOAP is another XML-based standard, and it predates the .NET platform. Essentially, when you send information to and retrieve information from your Web Service in a .NET application, your requests and responses are packaged in the SOAP format. The SOAP format looks similar to the HTTP response we got before, but it is not identical. The test web page shows the actual format for SOAP and HTTP requests and responses when you click on a method. Accessing a Web Service Directly
Now that you understand a little bit about the standards underlying Web Services, you may realize that you don't really need to go through the Internet Explorer test page, although it is very convenient.
To see the WSDL contract for a Web Service, just add ?WSDL after the filename in your Internet browser. This works for any .NET Web Service, including those that have been created by other developers. The Web Service WSDL contract for the PostalWebService can be retrieved with this line (assuming it's in a virtual directory called NoStarchWeb on the local computer):
http://localhost/NoStarchWeb/PostalWebService.asmx?WSDL
You can also interact with the Web Service through HTTP GET by typing the parameter list into the URL. In fact, if you enter the value 221 for the Get- PackageInfo function and click Invoke, this is what Internet Explorer links to:
http://localhost/NoStarchWeb/PostalWebService.asmx/GetPackageInfo?TrackID=221
In other words, Internet Explorer just passes the function name and the TrackID parameter as part of an HTTP GET request. At this point, you might start to realize that if communicating with Web Services is this straightforward, it really is possible to access them on different operating systems and platforms.
When IIS receives a web request like the one shown above, it passes it to the ASP.NET worker process, which then creates the Web Service. The Web Service runs the appropriate function, returns the result as an XML page, and is destroyed. The end result appears as a page in your Internet browser.
The next section looks at how .NET applications consume Web Services by using SOAP calls, which allows you to retrieve the results of a Web Service in a .NET program instead of a browser.
Consuming a Web Service
At this point, you've seen your Web Service in action, but you haven't usefully incorporated it into another program. Clearly, if users had to rely on the Internet Explorer test page, they would be better off with a full-featured Internet application!
In this section you'll learn how to create a Web Service client in VB .NET. Best of all, you'll learn how to get Visual Basic .NET to create all the infrastructure code you need.
The Proxy Class
Web Service clients communicate with Web Services through a proxy class that you can create automatically with the .NET framework. The proxy class translates your actions into the appropriate SOAP calls, and then interacts with the Web Service. The whole process is seamless, so you might not have even realized it was happening if you hadn't seen the following diagram:
Figure 13-5: Web Service interaction
Adding a Web Reference
To create the proxy class, you need to add a web reference in Visual Basic .NET. First, add a new Windows application project to the current solution by rightclicking on the Solution Explorer and selecting Add • New Project. This project should not be created in the virtual directory where the Web Service is located because it will not be hosted on the web server.
Then, right- click on the new project and select Set As StartUpProject. Now, right-click one more time, and choose Add Web Reference. The Add Web Reference window will appear (Figure 13- 6).
Figure 13- 6: Adding a web reference
To add a web reference, you need to supply a discovery file. A discovery file is the first step in the interaction process; it's where an application "discovers" what Web Services are available, what methods they have, and what information they require and return.
You may have noticed that Visual Basic .NET automatically added a .vsdisco file to your Web Service project. This is the file you now need to select. Click the Web References on Local Server link. On the right, a list will appear of the discovery files residing on your current computer. If you have already created an ASP.NET application, you may find more than one discovery file. Choose the one that is in the appropriate directory.
Once you have made your selection, information will appear about the Web Services specified by the discovery document you've chosen. You can click on the View Contract button to see all the WSDL information again, or click on the Add Reference button to link to this Web Service and generate the required proxy class automatically.
Inspecting the Proxy Class
Visual Basic .NET hides the proxy class it creates from you, because you don't really need to see it or modify it directly. However, it's always a good idea to peek under the hood of an application and get a better understanding of what's really happening along the way.
To see the proxy class, select Project • Show All Files from the menu. Then, look for the folder under Web References with the .WSDL file. Double- click to expand this entry, and you'll see the Visual Basic proxy file (typically called Reference.vb), as shown in Figure 13-7.
Figure 13- 7: The hidden proxy class
This file includes all the methods from your WebService, in slightly modified form. It also includes the ClientPackageInfo class that you need to use to retrieve the information from the GetPackageInfo method. Interestingly, Visual Basic .NET is intelligent enough to leave out the Package class, so the client will have no idea that the Web Service uses this class internally and won't be able to snoop out its internal details.
Take a quick look at the modified version of the GetPackageInfo function contained in the proxy class. (The attributes that precede it are not included here.)
Public Function GetPackageInfo(ByVal TrackID As String) As ClientPackageInfo
Dim results() As Object = Me.Invoke("GetPackageInfo", New Object() {TrackID})
Return CType(results(0), ClientPackageInfo)
End Function
This function converts the TrackID input string into a generic object, and retrieves the result as a generic object, which is then converted into the appropriate ClientPackageInfo object. In between, it accesses the Web Service through the appropriate SOAP request and waits for the response, although all this is taken care of automatically in the Me.Invoke method, with the help of the .NET attributes that provide additional information to the Common Language Runtime.
Another interesting aspect of the proxy class is the constructor, which sets the URL. If you change the location of your Web Service, you can modify this method, rather than regenerating the proxy class. Notice, however, that localhost is specified, regardless of the name of your computer. Localhost is a "loopback" alias that always points to the current computer.
Public Sub New()
MyBase.New
Me.Url = "http://localhost/WebService/PostalWebService.asmx"
End Sub
Using the Proxy Class
The proxy class is the key to using a Web Service. Essentially, you create an instance of this class, and call the appropriate methods on it. You treat the proxy class as though it were a local class that contained the same functions and methods as the Web Service.
Add the following code to the Load event of your startup Windows Form:
Dim ServiceInstance As New localhost.PostalWebService()
Dim PackageInfo As New localhost.ClientPackageInfo()
PackageInfo = ServiceInstance.GetPackageInfo("221")
MessageBox.Show("Received the delivery date: " & PackageInfo.DeliveryDate)
Now run the application. If Visual Studio .NET loads up the Web Service web page, you have to stop the project and set the Windows application as the startup project, using the right-click menu in the Solution Explorer window. If you have configured everything correctly, you'll see the window in Figure 13- 8.
Figure 13- 8: The Web Service results
Once again, the technical details are pretty sophisticated, but the actual implementation is hidden by the .NET framework. Calling a Web Service is as easy as creating one, once you have set up the web reference.
Debugging a Web Service Project
When debugging a solution that includes a Web Service project and client, you will find that any breakpoints or watches you set for the Web Service code are ignored. That is because, by default, Visual Studio .NET only loads the debug symbols for the startup project, which is the client.
To solve this problem, you need to configure Visual Studio .NET to load both projects at once. Right- click on the solution item in the Solution Explorer, and select Properties. Then, browse to the Common Properties • Startup Project tab, and specify Multiple Startup Projects, so that both your client and the Web Service will be built when you click the start button (Figure 13- 9).
Figure 13-9: Starting multiple projects
You still need to make one more change. By default, Visual Studio .NET starts the Web Service project by displaying the Internet Explorer test page. In this case, however, you don't want any action to be taken other than loading the debug symbols so that the Web Service code is available for debugging.
Right- click on the Web Service project, and select properties. In the Configuration Properties • Debugging tab, select "Wait for an external process to connect" as your start action (Figure 13-10). You can now use the full complement of debugging tools with your Web Service and client code.
Figure 13-10: Loading the Web Service debug symbols
Asynchronous Web Service Calls
You may have noticed that the proxy class actually contains more than just the GetPackageInfo function. It also includes BeginGetPackageInfo and EndGet- PackageInfo procedures. These routines allow you to retrieve a Web Service result asynchronously. For example, your code can submit a request with Begin- GetPackageInfo, perform some additional tasks, and then retrieve the result with EndGetPackageInfo. This allows your program to remain responsive, even when waiting for a response over a slow Internet connection.
Dim ServiceInstance As New localhost.PostalWebService()
Dim PackageInfo As New localhost.ClientPackageInfo()
' Create a special handle that will allow us to retrieve the result.
Dim ResultHandle As IAsyncResult
' Submit the request.
ResultHandle = ServiceInstance.BeginGetPackageInfo("221", Nothing, Nothing)
' (Perform other time-consuming tasks.)
' Retrieve the final result, using the ResultHandle.
PackageInfo = ServiceInstance.EndGetPackageInfo(ResultHandle)
MessageBox.Show("Received the delivery date: " & PackageInfo.DeliveryDate)
In this example, ResultHandle is a special IAsyncResult object that tracks the current request. You can have multiple asynchronous web requests submitted at the same, as long as you keep track of them with different IAsyncResult objects.
When the EndGetPackageInfo method is called, the request becomes synchronous. That means that if the response has not yet been received from the Web Service, your code will wait until it is received (or until the request times out, according to the proxy class Timeout property).
Alternatively, you can call BeginGetPackageInfo with the address of a subroutine in your program. When the Web Service result is received, this routine will be called automatically. This technique is ideal if you are requesting some information that is not critical, and you want to allow your application to continue its normal behavior. By using a callback, you can respond immediately when the information arrives, but your application doesn't need to sit idle waiting for it.
Here's an example where a button click submits an asynchronous request with a callback:
Private ServiceInstance As New localhost.PostalWebService()
Private Sub cmdAsyncCallback_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdAsyncCallback.Click
' Create a special handle that will allow us to retrieve the result.
Dim ResultHandle As IAsyncResult
' Submit the request, with a callback.
ServiceInstance.BeginGetPackageInfo("221", AddressOf ResultReceived, Nothing)
End Sub
When the result is received, the ResultReceived subroutine will be called immediately, and a MessageBox will appear alerting the user. (A more common action might be to use the information to update a portion of the user interface.) The PostalClient included with the online samples demonstrates these different ways of retrieving information from a Web Service asynchronously.
Private Sub ResultReceived(ByVal ar As IAsyncResult)
' Retrieve the final result, using the ar event arguments..
Dim PackageInfo As New localhost.ClientPackageInfo()
PackageInfo = ServiceInstance.EndGetPackageInfo(ar)
MessageBox.Show("Received the delivery date: " & PackageInfo.DeliveryDate)
End Sub
TIP You could also use the threading techniques described in Chapter 10 of The Book of VB .NET. For example, you could create a procedure that calls a series of web methods on a separate thread and then raises an event to notify your program.
Web Service Discovery
One aspect of this process that I've glossed over a bit is the discovery file. The discovery file represents Microsoft's goals for easily sharing Web Services and making them available to the appropriate clients. You don't need to worry about these sharing issues if you are creating a Web Service exclusively for use in your company website, or with a few select clients. However, if you are trying to develop and market a Web Service that provides powerful features that you want to provide as a subscription service, discovery matters quite a lot.
Discovery is the process that allows a client to find the WSDL information that describes your Web Service. Your server may have one discovery document that points to multiple Web Services, or it may have several different discovery files in various virtual directories. Alternatively, you might not use a discovery file at all.
A discovery document is yet another type of XML file. All it contains is a list of web links (URLs) to the WSDL document of various Web Services. Here is a sample discovery file for our PostalWebService:
<?xml version="1.0" encoding="utf-8" ?>
<disco:discovery xmlns:disco="http://schemas.xmlsoap.org/disco"
xmlns:wsdl="http://schemas.xmlsoap.org/disco/wsdl">
<wsdl:contractRef ref="http://fariamat/NoStarchWeb/PostalWebService.asmx"
</disco:discovery>
By default, discovery files use dynamic discovery, and look a little different. With dynamic discovery, every subdirectory in the current directory will be scanned for Web Services. Here is a sample dynamic discovery file:
<?xml version="1.0" encoding="utf-8" ?>
<dynamicDiscovery xmlns="urn:schemas-dynamicdiscovery:disco.2000-03-17">
<exclude path="_vti_cnf" />
<exclude path="_vti_pvt" />
<exclude path="_vti_log" />
<exclude path="_vti_script" />
<exclude path="_vti_txt" />
<exclude path="Web References" />
</dynamicDiscovery>
The exclude path attributes tell the discovery process not to look in those folders. This can be used to save time (for example, by restricting directories that contain only images), or to restrict a Web Service from appearing in a discovery process (although it will still be accessible unless you have specifically written authentication or security code).
TIP How can you add a web reference if you don't have a discovery file? You can manually type the Web Service location into the address bar of the Add Reference window. You don't even need to worry about supplying the ?WSDL at the end to locate the WSDL document, because Visual Studio .NET is smart enough to add that for you automatically.
What Comes Next?
This article has provided an overview of how Web Services work, and how to use them. Leading edge companies and developers have already started inventing all kinds of imaginative Web Services. Some examples include Microsoft's Passport, which allows other companies to provide authentication using the engine that powers the Hotmail email system, and CodeSwap (www.vscodeswap.net), a Microsoft-supported initiative that allows you to share code fragments with other developers as easily as you could once share MP3 files in the original Napster program.
If you want to continue learning about and working with Web Services, here are some interesting places to start:
• Microsoft provides a Web Services portal that provides such information as low-level technical information about the SOAP and WSDL standards, code samples of professional Web Services, and white papers discussing the best ways to design Web Services. Check it out at http://msdn.microsoft.com/ webservices.
• UDDI (Universal Description, Discovery, and Integration) is an emerging standard that will make it easy for developers to locate discovery files and available Web Services on the Internet. You can find more information, and some interesting examples of Web Services, at http://uddi.microsoft.com/ visualstudio.
• Various other Web Service search engines are appearing on the Internet. You can use them to see what other developers are up to. To get started, try out http://www.gotdotnet.com/playground/services and http://www.xmethods.com.
• Remember, you can enable Session support in a Web Service, and use some of the same techniques that you would use for authentication in an ASP.NET application. For more information, check out the MSDN help library.
Matthew MacDonald, an author, educator and MCSD developer, has worked with Visual Basic and ASP since their inceptions. He is the author of The Book of VB .NET (No Starch Press) and ASP.NET: The Complete Reference (Osborne McGraw-Hill) and co-author of Programming .NET Web Services (O'Reilly).
|