Introduction to WCF
June 26th, 2008 | by dmarcet |As a first approach to Windows Communication Foundation, I started reading the book "Microsoft Windows Communication Foundation Step by Step" by John Sharp.
On the first section of the post I’ll talk a little about the fundamental concepts of WCF and SOA; on later sections I’ll explain the steps that must be performed to define a simple WCF service and host it in IIS will be described in the following sections. And on a future post I’ll be writing a little about hosting the service on a different host other than IIS.
Fundamentals of WCF and SOA
Endpoints
A host application makes a service available to client applications by providing an endpoint to which clients can send requests. An endpoint contains three pieces of information commonly known as ABC: Address, Binding and Contract.
- Endpoint Address:
The form of a service address depends on several factors, including the transport protocol being used. Different transport mechanisms use different address spaces. If you build your own custom host application, you can use a different transport mechanism, and you must specify an address that is appropriate to your chosen transport mechanism.
- Binding:
The binding for a service describes how a client can connect to the service and the format of the data expected by the service. The presence of each binding element describes part of the how of communicating with the Endpoint since for each binding element a channel will be created on the channel stack (see the next section Processing a Client Request)
- Contract Description:
A WCF service contract is an interface stored in a .NET Framework assembly and annotated with the [ServiceContract] attribute. The service contract describes the operations implemented by the service by tagging them with the [OperationContract] attribute. Any data passed to and from operations must be serializable.
Processing a Client Request
When a request arrives to the WCF Service’s host, it goes through a channel stack where each element is a channel that receives the message, transforms it in some way (for example decodes it if it’s on binary format, decrypts it if it’s using Asymmetric encryption, etc.), and passes the output as input to the next channel on the stack.
Although there is no order on the channel stack, a transport channel will always be at the bottom of the stack and will be the first channel to receive data from the network. Also an encoding channel must be the first element of the stack. These two channels are the only mandatory, all the rest are optional.
SOA’s 4 Tenets
An Service-Oriented Architecture consists of a set of resources on a network that are made available as independent services, and that can be accessed without requiring any knowledge of how they are implemented. To successfully design and implement an SOA, you should be aware of what has become known as the “Four Tenets of Service Orientation”:
- Boundaries are explicit
Applications and services communicate by sending messages to each other:- You should not make any assumptions about how a service processes a request or how a client application handles any response to a request.
- Because of the associated cost in terms of communications when sending and receiving messages. You should design the operations that services implement with this in mind, and ensure that clients call services only when necessary.
- The services must be easy to consume, for that the client perspective must be taken into account.
- Keep the service’s scope as small as possible because the more operations the service expose, the more difficult will be to use it by clients.
- Never expose details of internal implementation.
- Services are autonomous:
If you are building an application based on services, you might not have control over every service you are using.- Design the service decoupled of the platform in which will be deployed and will be consumed.
- Contracts must be designed considering that once deployed they can’t be changed.
- Adopt a pessimistic position: for providers, there will be clients who will make a bad use of the service; for clients, the services will fail or won’t be available.
- Services share schema and contract, not class:
Services publish information about the operations that they implement and the structure of the data that they expect to send and receive. Clients use this information when communicating with the service.- The contract of the service must be maintained stable, if it’s updated it should maintain compatibility with existing clients by continuing to implement existing contracts and send messages that conform to existing schemas.
- Contracts must be clear and explicit to avoid bad interpretations.
- Keep the internal implementation hidden.
- Version services when changes to the service’s contract are unavoidable. This approach minimizes breakage of existing consumer implementations.
- Service compatibility is based upon policy:
The schemas and contracts exposed by a service define the “shape” of the service but not the nonfunctional requirements that a client attempting to access the service must fulfill. These nonfunctional requirements might change over time and so should be decoupled from the service’s and client’s implementation. You should design services so that their policy requirements are independent of any implementation, and you should enforce clients to abide by any policies required by the service. Additionally, all services and client applications must agree on how to specify this policy information (typically by using some sort of configuration file). This is the purpose of the WS-Policy framework, published by the World Wide Web Consortium, and widely adopted by Web service developers.
Writing your first WCF Service
Define the contracts
As WCF adopts a contract-first the first step to create a service is to define the contract, which is done by defining an Interface. This interface has the only peculiarity that must have a ServiceContract attribute to mark it as a service contract, besides each of the methods that wants to be exposed must have a OperationContract attribute to expose it in the service.
The parameters and values returned can be of any kind as long as WCF can serialize and deserialize them, this includes the native types (int, bool, string, etc), collections (including generics) and Datasets.
To pass your own classes as parameters and return values, you can also define a data contract. To do this add the DataContract attribute to the class and the DataMember attribute to each of the properties that you want to expose of this class, these can be of any kind that WCF is able to serialize/deserialize to XML including other classes tagged with DataContract.
By doing this you’ll be marking the class as serializable and WCF will handle the persistence to XML.
Implement the service
Once you have defined the contract you have to define the class that will implement the contract (interface). Remember that even if you declare public members in this class, if they are not defined in the contract they won’t be visible for the users of the service.
Configure the service
Now that you have your service defined it’s time to configure the service, this will depend on how you will be deploying it. For this example I’ll be explaining how would you do it on an IIS deploy.
The first step is to define an .svc file that will represent the service as a special content file to IIS (in a similar way as ASMX pages are represented inside of an IIS application as .asmx files). The name of this file must be exactly the same as the service binary. Inside this file the WCF-specific processing directive @ServiceHost must be contained, that will allow the WCF hosting infrastructure to activate hosted services in response to incoming messages. For this example the content of the file would be the following:
The last step is to add the service configuration to the .config file (web.config in this case since it’ll be hosted on IIS, app.config otherwise).
The <serviceModel> section of the Web.config file contains the configuration information for a WCF Web service. The <services> section contains the details for each service implemented. The name attribute of the <service> element specifies the namespace and class that implement the service. The <endpoint> element provides the details of the service that client applications require in order to communicate with the service. An endpoint comprises three pieces of information: an address, a binding, and a contract.
- The address is the location that the application hosting the service uses to advertise the service. In the case of IIS, the address element actually is ignored as IIS will use a URL containing the name of the virtual directory holding the service and the name of the .svc file as the endpoint.
- The binding element specifies items such as the transport mechanism used to access the Web service, and the protocol to use, amongst other items. For a complete list of the binding elements see "Windows Communication Foundation Bindings".
- Finally, the contract element indicates the contract that the service implements.
The last action on the Project is changing the Output path to \bin (instead of \bin\Debug or \bin\Release). This has to be done because IIS expects the assemblies containing the code for Web services and Web applications to be located in the bin folder of the Web site.
To do this right-click on the WCF service project and select the Properties option, then select the Build tab and change the Output path to \bin.
Now it’s time to create the web application, I’ll show you how to do it on IIS 7.0 (included with Windows Vista and Server 2008), on previous versions of IIS the process is very similar but you’ll have to use Virtual Directory instead of Application.
On the IIS Manager, right-click on the Default Web Site node and select the Add Application… option.
For the Alias select any name you like, this will be part of the URL how you’ll invoke the service, to be consistent I used ProductsService. For the Physical Path select the ProductsService’s project folder.
And that’s it! You have a fully functional WCF Service hosted on IIS
To check if it’s running you can browse http://localhost/<alias selected>/ProductsService.svc and a page like the following should show up on the browser.
Final thoughts
Windows Communication Foundation is a very complex topic and I’m sure I’ll continue studying it for a long time so expect more posts about it in the future!
Besides the mentioned book, I got recommended "Inside Windows Communication Foundation" as a continuation book for this one since it covers lower level subjects on WCF.
Lessons learnt
- When hosting a WCF service in IIS, you must have the .svc file extension handled. If you installed IIS after installing WCF as I did, you’ll have to configure the IIS in order to have your WCF services hosted on IIS working. To accomplish this you have two options, you can do it through command line or through the windows UI (only tested on Windows Vista Business).
For the first option you can check the steps at "Service (.svc) File Type Not Recognized", for the second option go to Control Panel->Programs and Features and select Turn windows features on or off, there check the options under the Microsoft .NET Framework 3.0. -
Another problem I had was when trying to attach the AdventureWorks database to my SQL Server 2005 Express Edition. Since it was installed with Server authentication set to Windows Authentication mode, and the only user with administrator permissions was the "sa" user which was disabled because its login uses the SQL Server Authentication mode; I couldn’t execute any administrative action, including database attaching. To solve this problem:
-
Run the MS SQL Server Management Studio as an administrator.
-
Go to Security->Logins, right-click on your Windows user and select properties.
-
On the left menu (Select a page), select Server Roles.
-
Finally check the sysadmin and dbcreator server roles and that’s it, you can now run the Management Studio app normally and log-in with your Windows user and you will have permissions on system databases to create and attach new databases.
-
You must be logged in to post a comment.