Introduction
WCF is good. Perhaps great. It fixes a bunch of problems we never knew existed, and adds a bunch more brand new, exciting ones. If you use Web Services, .NET Remoting, or any other wacky scheme to have a program communicate with another program (or application tier or server or process or whatever), WCF is for you.
It’s very powerful. It’s very flexible. Unfortunately, this also means it’s very difficult to find easy answers on how it works. I’m going to show you, as quickly and simply as possible, how to get up and running with WCF under a common and useful scenario. Understand, though, that I’m just presenting a quick tutorial on one way to use WCF; I’m not showing you how all of WCF works.
For quick solutions to some of the more common pitfalls you may encounter, and to read the next WCF article I'm writing section by section as it's written and revised, check out www.slickit.ca. You'll also find ways to contact me directly there in case you need a bit of personal assistance.
Building a Basic WCF Service
WCF is based around the idea of Services. A Service is essentially a class that you can access from outside of the application where the class lives, even across the Internet. Let’s have a look at a simple WCF service:
Imports System.ServiceModel
<ServiceContract()> _
Public Class Test
<OperationContract()> _
Public Function GetLocalTime(ByVal includeDate As Boolean) As String
If includeDate Then
Return Now.ToString
Else
Return Now.TimeOfDay.ToString
End If
End Function
End Class
As you can see, it’s really just an ordinary class. <ServiceContract()>
marks the class as a WCF service, and <OperationContract()>
marks the function as an operation of the service, so that you can access it outside of its application. In many samples, you’ll see this class split between an interface (the contract) and a class (the service). This is probably a good idea, but it’s not required.
If that code won’t compile, you probably need to add a reference to System.ServiceModel
.
Believe it or not, that’s it. You’ve made a service. Easy!
Hosting a Basic WCF Service in IIS
Okay, so you’ve made a wonderful WCF Service. It tells the time and everything! But how do you use it? Well, that’s where things get a bit complicated.
There are many ways you can host this service, and many ways clients can access it. You can host the service in a stand-alone application, or in a Windows Service you’ve written. You can use something called Windows Process Activation Service. Or, you can use good old IIS. Using IIS has a few nice advantages: you get to use all the power and configuration of IIS, it’s easy for people to understand what’s happening, even if they don’t know WCF, and it’s easy for other applications to use the service – even if they’re not built with .NET.
You also have to choose a binding. A binding is essentially a means of communication, and there are many to choose from. You can choose HTTP (in many flavours), TCP, named pipes, MSMQ, and so on. We’re going to look at basicHttpBinding
, which is nice and simple to work with and highly compatible.
So, if we’re hosting in IIS, we clearly need a virtual application folder in which to run our service. Let’s call this web WCFTest
. Then, use IIS Manager to allow anonymous authentication so we don’t have to worry about security concerns for the time being.
We’ll need to add three files to our web. First, we need the assembly containing the service you wrote. I’ll assume you created the service I just showed you, and you put it in a class library (DLL project) called WCFTest
. When you compiled that project, you made a file called WCFTest.dll. Create a folder called ‘bin’ in your web, and copy this file there.
Second, we need to add a *.svc file to the web. This file represents the address that clients will use to access the service, and it tells IIS where to find the service to use. Let’s call this file Test.svc. It needs to contain the following:
<%@ ServiceHost Service="WCFTest.Test" %>
ServiceHost
tells the server that this URL represents a WCF Service. Service="WCFTest.Test"
tells the server what class to use to run the service. Because we put our *.dll file in the /bin folder, the server will automatically find the class and be able to use it. There are other ways of organizing this, but this is perhaps the simplest to understand.
Finally, we need a web.config file placed in the web’s root to tell the server how to configure the service. Here’s what you need::
="1.0"
<configuration>
<system.serviceModel>
<services>
<service name="WCFTest.Test">
<endpoint address="" binding="basicHttpBinding" contract="WCFTest.Test" />
</service>
</services>
</system.serviceModel>
</configuration>
You can see that we’ve configured one service, called WCFTest.Test
, and we’ve created one endpoint using basicHttpBinding
. You can see that for the contract we’re using the same class as the actual service itself, but if you want, you could define the service contract (as an Interface) in one assembly and then implement the service itself (as a class that implements your interface) in another class or assembly.
Now, when you browse to http://localhost/WCFTest/Test.svc, you’ll see a web page that states you’ve accessed a WCF service. The rest of the page talks about metadata. Right now, your service is up and running. If you had any clients using the service, they’d be working.
But, you don’t have any clients using this service. And without metadata, you’re going to find it tough to build one. Metadata tells other programs how your service works and how to use it. Once they know this, they don’t need the metadata anymore, but to get there, we’re going to expose the metadata through IIS. To do this, we’ll change our web.config file to add another endpoint. This endpoint will use mexHttpBinding
, which is a metadata exchange format. We’ll set the address to /mex, and we’ll also define and set a serviceBehavior
, which allows you to specify more detailed options about how your service works. Here’s how your new web.config file should look:
="1.0"
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="basicBehavior" name="WCFTest.Test">
<endpoint address="" binding="basicHttpBinding" contract="WCFTest.Test" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="basicBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Now, metadata about your WCF service is available at http://localhost/WCFTest/Test.svc/mex. You won’t be able to browse it with Internet Explorer, though; it’s not meant to be used by a web browser. You can, however, browse to http://localhost/WCFTest/Test.svc?wsdl to see an XML version of your metadata.
At this point, your service is up and running in IIS, and metadata about your service is available so other programs will know how to access and use it.
WCF: Calling a Basic WCF Service
So, you’ve built a WCF service and you’ve hosted it in IIS. Now you want to access this service. How? We’ll, we’re back to things being easy!
Using Visual Studio 2008, just go to Project, Add Service Reference. Type URL of the service you built and choose a name for your new reference. Once you click OK, you’ll be able to use your service just as though it was a class in your project:
Dim wcfTest As New svcTest.TestClient
Dim sTime As String = wcfTest.GetLocalTime(True)
If you’re still using .NET 2.0, you can also add a Web Service Reference, and consume your WCF service just as though it were a traditional ASP.NET Web Service using the ?wsdl
metadata that’s generated.
Troubleshooting
If you ran into a problem anywhere in this tutorial, here are some things that might be giving you trouble.
Different Versions
If you know what you're doing, WCF is supported under many configurations. When you're just getting started, though, you want everything to be as simple as possible. You'll have by far the best experience using these versions:
- .NET Framework 3.5 with SP1
- Visual Studio 2008 (avoid Express editions)
- IIS7 (Windows Vista, Windows Server 2008, Windows Seven, or Windows Server 2008 R2)
Configuration Files
Editing the configuration files will probably be the toughest part of this tutorial. Take the time to fully examine all the XML so you understand what each node does. Even if the error seems cryptic, it will probably at least point you to the part of the configuration that needs fixing.
Case Sensitivity
This one is for all you VB developers out there. Take heed: these configuration files are case sensitive!
Security Errors
You shouldn't need to do this, but it can often help to run VS2008 as an Administrator to help rule out any security related problems.
Integrated Authentication
If you enable Integrated Authentication, you may receive this error:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.
If so, you'll have to adjust your configuration files to match your IIS configuration. For more information on this, see my post titled Using IIS and Windows Authentication to Secure WCF Services on Slick IT.
More Resources
Hopefully, you now have a basic understanding of how to at least get a really simple example running under WCF. If you learn by experimenting, you should be away to the races. If, however, you'd like to read a bit more about WCF before setting out on your own, here are some helpful pages you might not find on your own:
- MSDN's introduction to WCF. This should be your first point of reference. The Getting Started Tutorial is a bit lengthy and complex for beginners, but it is very good reading for those who want to learn the 'Microsoft' way of doing WCF. Highly recommended.
- Nikola Dudar's Blog. Here you'll find a similar approach to this article. Based in C#, this tutorial focuses more on the VS2008 tools and features available to help you write WCF services. It also introduces the WCF Service Host, a very helpful little utility.
- If broken it is, fix it you should. This is a C#-based introduction that goes into a little more depth on the code side of things.
- Kirk Evan's Blog. Here's a trick to invoke WCF services dynamically, which is very helpful if you don't have the metadata of the service you're calling available until runtime.
- J.D. Meier's Blog. This blog has a huge list of articles and videos to help you out with a variety of security-related topics.
- All About Interop. This site has a wealth of WCF-related information. You'll find lots of details on connecting your application with others through WCF, as well as some great screencasts and guides.
Conclusion
As you can see, WCF Services are very easy to build and use. Configuring them takes a bit of learning, but the beauty of WCF is that you can write your service in one place, consume your service somewhere else, write code as though everything was happening in one program, and then use configuration files to connect them however you need.
Yes, it’s new, and takes some serious learning to fully understand. No, it’s not perfect. But it is very much a step in the right direction. If you're able to use .NET 3.5 on your next project, you should really give WCF a try.
History
- 9th March, 2009: Initial post