WCF on Windows Azure
One thing we’ve had for a while but I wanted to bring some attention to is our “wcfazure” code gallery page that has a useful set of known issues and a number of samples on using WCF on Windows Azure.
It’s been updated recently to be more clear and to use all of the latest tools and such so even if you knew about it before, I recommend taking another look.
For the most part, WCF on Windows Azure just works. That said, there are a couple of issues to be aware of that are covered on the wcfazure code gallery page. That said, by in large, the most common issue I get asked about around WCF and Windows Azure is Generating Proxies so let me walk through this scenario.
First, I’m using Visual Studio 2010, but I’ll be using .NET 3.5 instead of .NET 4 because at this point in time (end of May 2010) we only support .NET 3.5 on Windows Azure. That will be changing with our next release.
The other reason to use .NET 3.5 is that the scenario in .NET 4 pretty much works out of the box. I’ll talk more about that after I explain how this works on .NET 3.5.
Create a new .NET 3.5 Cloud Service by clicking on File | New | Project… and select the Windows Azure Cloud Service template under the Cloud category in Visual C# or Visual Basic. Click to continue.
In the Feb 2010 release of the Windows Azure Tools 1.1, even if you select .NET Framework 4, you’ll still get .NET 3.5 roles but that won’t be the case when .NET 4 support comes online.
Add a WCF Service WebRole to the solution and click OK.
Hit F5.
Two things to notice. First, the browser will open to https://127.0.0.1:81/Service1.svc and you’ll see that even though the service is running on port 81, the page says to click on a link that is pointing to port 5100 which if you click the link will fail.
If you navigate to the Common7\IDE directory inside of the Visual Studio install directory and run WcfTestClient.exe, right click on “My Service Projects” and select “Add Service…”:
It too, will fail:
Add Service Reference and Svcutil will also not success in generating proxies. This is true not only in the devfabric but also on the cloud.
In order to fix this problem, we have a patch that can be found at the following locations:
OS | Download | Support Page |
Vista/Server 2008 | https://code.msdn.microsoft.com/KB971842 | https://support.microsoft.com/kb/971842 |
Win7/Server 2008 R2 | https://code.msdn.microsoft.com/KB981002 | https://support.microsoft.com/kb/981002 |
The problem is not specific to Windows Azure per se, it is specific to using WCF from behind a load balancer which is how your service runs on Windows Azure.
After installing the patch, there is still one more step you need to take in order to make the scenario work. You have to make a modification to your web.config.
I added a useRequestHeadersForMetadataAddress element under the behavior for my service.
<behavior name="WCFServiceWebRole1.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="81" />
<add scheme="https" port="444" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
The port attribute has to match the port for the endpoint that gets used.
On the devfabric, you’ll notice that even though your service asks for port 80, it gets port 81. That is because ports are dynamic and a port is in use, the devfabric increments the port number and tries again.
This isn’t a problem in the cloud, in the cloud if you declare your endpoint to use port 80, it’ll get port 80 and that’s what you should set the port attribute to in your web.config.
Hit F5. Browse to https://127.0.0.1:81/service1.svc if necessary.
This time you’ll see the URL on the web page looks right and clicking on it does indeed surface the WSDL.
Additionally, going back to the WCF Test Client and selecting to “Add Service…” this time it will work.
You can even use the test tool to invoke methods if you want.
Because this patch is installed in the Windows Azure cloud, if you followed the steps to update your web.config, you can also generate metadata against a WCF service hosted on Windows Azure.
Here's the really good news:
The patch is included as part of .NET 4 and for most scenarios only requires that enableMultipleSiteBindings must be set to true (the default in the template).
In other words, the default scenario for generating proxies for .NET 4 WCF services will work as expected for Windows Azure Cloud Services - on both the local DevFabric and in the Cloud.
Comments
- Anonymous
May 01, 2013
I noticed when I added the default ports to my load balanced web role the load balancer was sending all traffic through one instance. I took out the <defaultPorts> tag, and just used the self terminating <useRequestHeadersForMetadataAddress /> and requests were balanced between both instances again, and the URIs were still correct in the WSDL