CityView App: Build Web Service Clients Quickly and Easily with C# | |
Jeff Prosise | |
Download the code for this article:CityView.exe (45KB) Browse the code for this article at Code Center: CityView |
|
f Microsoft is correct, Web Services will play an important role in the future of the Internet. A Web Service is an application that exposes Web methodsâ€"functions that can be called over the Internet (or, if you'd prefer, an intranet)â€"to interested clients. It runs on a Web server and listens on port 80 for Simple Object Access Protocol (SOAP) packets that represent requests to execute a particular method. When a request arrives, the Web Service extracts the XML-encoded method name and parameters, executes the corresponding method, and returns the results as XML.
If you package this code in an ASMX file and place it on a Web server outfitted with ASP.NET, any client than can access the file's URL can also call the GetGreeting method. Although not shown here, writing a client for the GetGreeting method is almost as easy as writing the Web Service itself, thanks to another class in the .NET Framework class library named SoapClientProtocol and a utility named WebServiceUtil that generates SoapClientProtocol-derived proxy classes. The CityView Application Before I dive down under the hood to show you what makes my TerraService client tick, let's take a look at what a user sees. The application, which I named CityView, is shown in Figure 1. It displays a composite image of San Francisco (courtesy of the U.S. Geological Survey). The image is formed from 200x200 pixel tiles fetched from TerraServer via TerraService. The City menu features commands for fetching images of preselected cities and also a command that pops up a dialog box for entering the city and state of your choice. The Scale menu lets you select a resolution. Select a smaller number to zoom in for a more detailed view, or a larger number to zoom out and see more of the city.
LonLatPt and Place are both data types defined by TerraService. LonLatPt encapsulates a longitude and latitude, while Place represents a placeâ€"city, state, and countryâ€"somewhere in the world. With this method to call upon, converting an arbitrary place name such as San Francisco, CA into a longitude and latitude is as simple as this:
This example assumes that ts is a reference to a TerraService proxy objectâ€"an object that converts method calls into SOAP requests and transmits them to TerraService over the Internet. Exactly how you go about getting that reference will be discussed shortly.
The following statement uses GetAreaFromPt to retrieve a bounding box suitable for framing a 640�480 pixel image of the terrain at the longitude and latitude represented by point at a resolution of 32 meters:
Once the bounding box is computed, all you need to do is fetch from the TerraServer database all the 200�200 pixel images (tiles) that intersect that box and glue them together to create a composite image. Individual tiles are fetched with the GetTile method, which returns an array of bytes representing the pixels:
The TileID passed to GetTile can be retrieved from the AreaBoundingBox. Because there's a bit of work involved in fetching all the tiles and creating an image from them (mostly work involving the GDI+, which is a superset of the Windows GDI), I won't show the image retrieval code just yet. What's important for now is that I used only three of the Web methods that TerraService exposes to create an application that's a real conversation piece. Most people are amazed the first time they see it in action. They're even more amazed when they see how little code it took to make it work. Creating a TerraService Proxy To invoke methods on a Web Service such as TerraService, you need code that encapsulates requests in SOAP "envelopes" and squirts them out through an HTTP connection. There are two basic ways to write that code. There's the hard way, which means using the SOAP Toolkit (or, if you'd prefer, no toolkit at all) to write the code from scratch. And there's the easy way, which involves deriving a class from the .NET Framework class library's SoapClientProtocol class and letting it do the work for you. The easy way is made even easier by the fact that you don't have to perform the derivation by hand. Instead, you can use the WebServiceUtil utility that comes with the .NET Framework SDK. Together, WebServiceUtil and SoapClientProtocol make it trivial to write Web Service clients. You don't have to know the first thing about SOAP to use them because they hide SOAP way down under the hood where network protocols belong. (You don't have to understand TCP/IP to use sockets, do you?)
The /C switch tells WebServiceUtil to generate a proxy class (derived from SoapClientProtocol) that can be used to call TerraService's Web methods. The /L switch instructs WebServiceUtil to generate C# code (as opposed to Visual Basic®), and the /N switch tells it to enclose that code in a namespace named TS. (The namespace is necessary to prevent name collisions between TerraService data types and certain data types defined in the .NET Framework class library.) The /PATH switch identifies TerraService's Service Description Language (SDL) URL. WebServiceUtil uses the URL as the target of an HTTP GET and receives in return SDL data describing TerraService's Web methods, data types, and supported protocols. It is from this SDL that WebServiceUtil determines what methods to build into the proxy class. The CityView Code Once you've generated TerraService.cs, you have everything you need to begin writing the CityView client (or any other TerraService client, for that matter). CityView's source code is shown in Figure 2. It's written in C# and was compiled using the Beta 1 .NET Framework SDK. Note that it will need some minor tweaking to compile under Beta 2. If you'd like to compile the code yourself, go to the directory where CityView.cs and TerraService.cs are stored and type the following at the command prompt:
This command invokes the Microsoft C# compiler and produces CityView.exe from the source code files CityView.cs and TerraService.cs. The /REFERENCE switches identify assemblies containing the external data types that CityView uses which aren't defined in MsCorLib.dll. Drop Me a Line Are there tough Win32®, MFC, COM(+), or .NET programming questions you'd like answered? If so, drop me a note at jeffpro@wintellect.com. Please include "Wicked Code" in the message title. I regret that time doesn't permit me to respond to individual questions, but rest assured that each and every one will be considered for inclusion in a future column. |
|
Jeff Prosise is the author of Programming Windows with MFC (Microsoft Press, 1999). He is also a cofounder of Wintellect (https://www.wintellect.com), a Windows developer training and consulting firm. |
From the April 2001 issue of MSDN Magazine.