Trying to Communicate

Visual Studio 2008 embraces the exciting new world of Windows Communication Foundation (WCF) for communicating with services. However, pitfalls await the unwary. I’ve recently tackled invoking the Reporting Services Web service with WCF and I want to share my findings.

  1. The Visual Studio Add Web Reference menu has been renamed to Add Service Reference to denote that WCF can communicate with much more than Web services, including probably my Zune device. Although the dialog has somewhat changed, you will be find your way to generate the proxy.
  2. What’s more surprising is that the auto-generated proxy methods now have somewhat different signatures.

For example, the SQL Server Books Online has the following signature of the Reporting Services GetExecution Options API.

public ExecutionSettingEnum GetExecutionOptions (string Report,out ScheduleDefinitionOrReference Item);

Yet, WCF generates the following signature:

public ServerInfoHeader GetExecutionOptions(string Report, out ExecutionSettingEnum executionOption, out ScheduleDefinitionOrReference Item);

So, the returned value becomes an out parameter while ServerInfoHeader becomes a returned value. I am not sure how WCF figures this out. Does it mean that now the documentation should show both the 2.0 and WCF signatures?

  1. The second surprise wave hit me when I was trying to figure out a way to pass my credentials to the Web service. This, of course, will probably be one of the first things you need to do to invoke an Intranet service.

In the good ol’ 2.0 days, impersonating the user takes a single line of code.

rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

How do we this in the shiny new WCF world? Strangely, the Visual Studio help says little about this. I came across some bizarre examples of declaring HTTP transports that made my head spin. In a sheer stroke of luck, I managed to figure out the right changes in the application config file (yes, now we have declarative settings).

<security mode=”TransportCredentialOnly“>

<transport clientCredentialType=”Ntlm” proxyCredentialType=”None” realm=”” />

<message clientCredentialType=”UserName” algorithmSuite=”Default” />

</security>

Wait! We need to tell WCF also that is OK to impersonate the user.

ReportingService2005SoapClient rs = new ReportingService2005SoapClient();

rs.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

At this point, I felt like upgrading my house only to find that I have to enter through the chimney. Upgrading to a new technology shouldn’t complicate things unnecessarily. I promptly switched back to the 2.0 style of programming. Luckily, they kept the old Add Web Reference button from the advanced settings of the Add Service Reference dialog.

I guess they were right. You can’t teach an old dog new tricks…

Happy holidays!