Saturday, January 24, 2009

Consuming ArcGIS Server SOAP services in Silverlight 2.0

Microsoft's Silverlight platform offers yet another application environment in which to consume SOAP services. The Silverlight platform is truly tantalizing - the ability to blend\mash\mix services and data with a rich user experience in a web client is undeniably sexy and powerful. Unfortunately some of the backend plumbing still needs to be worked out. This includes Silverlight's ability to consume SOAP services, let alone ArcGIS Server's SOAP service stack. Sure, everyone's talking about REST and WCF, but W3C standard, contract based, explicitly typed interaction with SOAP services is still prevalent - just take a look at the recent release of the Virtual Earth Web Service SDK.

So how do you consume a SOAP service in a Silverlight application or class library? Once you install the Silverlight tools with Visual Studio (or Web Developer) 2008 sp1 you will be provided with a context menu item off the project in Solution Explorer. The item is named "Add Service Reference" and opens a dialog box for a developer to define the endpoint to a service (WCF,SOAP) and a namespace for the native client types that will be generated.

This capability is synonymous with the "Add Web Reference" capability for SOAP services in standard .NET projects. A single url to a WSDL is used to construct a SOAP proxy and a set of value object types. This provides a nice interface for one-off services, but if you have a set of services that share value object types and you want to generate a single library with a single namespace, you need to use a command line tool. This is possible with the NET 2.0 and 3.5 SDKs which include the web service utilities wsdl.exe and svcutil.exe, respectively. Note, wsdl.exe output is supported in .NET 2.0 - 3.5. Unfortunately Silverlight does not provide the same or similar utility. Before Silverlight 2.0 final was released, a utility named slwsdl.exe was available for this purpose. Unfortunately it was removed from the 2.0 final release for reasons unknown. In addition, the output from wsdl.exe and svcutil.exe will not work with Silverlight applications. Both wsdl.exe and svcutil.exe generate references to types that are not available in the Silverlight platform. Problematic type references generated in svcutil.exe output can be removed so reference code can actually be built as a Silverlight class library. Unfortunately the proxy class includes both synchronous and Begin\End asynchronous methods. Neither pattern is supported in a Silverlight application. In fact, the Silverlight "Add Service Reference" tool only generates Async\Completed asynchronous methods, which is the "promoted" pattern for event-based asynchronous programming. Apparently there is no way to trigger svcutil.exe to only generate the appropriate asynchronous methods for Silverlight and synchronous methods are not officially supported in Silverlight, apparently due to cross-browser support issues.

So with all this in mind, how can you generate a single library that contains all the proxy classes and value object types for all ArcGIS Server service types? It’s hokey, but you need to manually merge all WSDLs into a single WSDL – being careful to place the element types in the same locations (e.g. element vs. operation, etc.). You only need to do this once since the library you generate will be distributable thus reusable for all Silverlight applications\libraries. In fact, the sample included with this post includes the reference class file generated from this process, so you don’t need to mess around with the ArcGIS Server WSDLs – just download the sample and compile the ArcGIS_SOAP_Silverlight project. Or just use the precompiled ArcGIS_SOAP_Silverlight.dll in the bin folder.

The sample is available here.

The sample also contains a Silverlight application that illustrates a simple use case for consuming an ArcGIS Server dynamic map service and navigating the map. Left mouse click on the map zooms in, Shift+left mouse click zooms out. Note you’ll need Visual Studio 2008 sp1 and the Silverlight tools to load and build the projects in the solution (see for more info). You can give a test run below. It's designed to be instructive, so it's pretty simple.

One additional note, the Web site that hosts the ArcGIS Server services must have a clientaccesspolicy.xml(Silverlight) or crossdomain.xml(Flex) in place to support cross domain\site requests. Silverlight will work with either. If using crossdomain.xml the following entry will enable SOAP interaction for all consumers:

<allow-http-request-headers-from headers="*" domain="*">