Visual Studio 2010 offers some project templates for creating WCF projects. Table 1 lists them all.
Table 1. WCF Project Templates
Template | Description |
---|
WCF Service Application | Used for creating a self-hosted WCF service |
WCF Service Library | Used for creating a WCF service to be manually hosted and configured |
WCF Workflow Service | Allows creating a WCF service with integration with Workflow Foundation |
WCF Syndication Library | Generates a WCF service enabled for RSS syndication |
WCF RIA Services Class Library | Only available within Silverlight projects, allows adding a WCF service with Silverlight integration |
A WCF service cannot be run
or consumed as a standalone and must be hosted inside a .NET
application. Host applications can be of several types: Console
applications, Internet Information Services, and ASP.NET Development
Server are all valid host applications. The WCF Service Application
template provides hosting inside the ASP.NET Development Server that
ships with Visual Studio and is appropriate for local testing purposes.
Select the File, New Project command, and in the New Project dialog select the WCF Service Application template, as shown in Figure 1. Name the new project as BookService and then click OK.
The goal of the example is to
offer a way for validating books’ information, such as ISBN code, title,
and author. The service exposes a Book class representing a single book and a method named ValidateBook
that provides the validation logic. Before writing custom code, taking a
look at the auto-generated code is a good idea for understanding what
WCF needs. Visual Studio 2010 generated a Web project visible in
Solution Explorer. The new project contains the following files:
IService1.vb, which defines the contract interface
Service1.svc.vb (nested into Service1.svc as a code-behind file), which defines the class that implements the contract
Service1.svc, which is the actual service that exposes data and that is be consumed by clients
Web.config, which provides definitions for the ABC
Let’s take a look at the IService1.vb file, which is reported in Listing 1 and that defines a couple of contracts.
Listing 1. Auto-Generated Contracts
' NOTE: You can use the "Rename" command on the "Refactor" menu ' to change the interface name "IService1" in both code and ' config file together. <ServiceContract()> Public Interface IService1
<OperationContract()> Function GetData(ByVal value As Integer) As String
<OperationContract()> Function GetDataUsingDataContract(ByVal composite As _ CompositeType) As CompositeType
' TODO: Add your service operations here
End Interface
' Use a data contract as illustrated in the sample below ' to add composite types to service operations. <DataContract()> Public Class CompositeType
<DataMember()> Public Property BoolValue() As Boolean
<DataMember()> Public Property StringValue() As String End Class
|
The IService1 interface is decorated with the ServiceContract
attribute, meaning that it establishes what members the service defines
and makes available to the public. The interface defines two methods,
both decorated with the OperationContract
attribute. Such attribute makes methods visible to the external world
and consumable by clients. You need to remember that in WCF marking a
method as Public is not sufficient to make it available to clients; it needs to be marked as OperationContract to be visible. Methods exposed by WCF services are also known as service operations. Notice how the GetDataUsingDataContract method receives an argument of type CompositeType. This type is a custom class declared as DataContract, meaning that the WCF service can exchange data of this type. Members from this class also need to be marked as DataMember to be visible to the external world. As for service operations, marking a member as Public is not sufficient; you need to decorate members with the DataMember attribute. The Service1 class shows an example of implementing the contract and the logic for service operations. Listing 2 shows the auto-generated sample code.
Listing 2. Auto-Generated Contracts Implementation
' NOTE: You can use the "Rename" command on the "Refactor" menu to ' change the class name "Service1" in code, svc and config file together. Public Class Service1 Implements IService1
Public Sub New() End Sub
Public Function GetData(ByVal value As Integer) As String _ Implements IService1.GetData Return String.Format("You entered: {0}", value) End Function
Public Function GetDataUsingDataContract(ByVal composite As CompositeType) As _ CompositeType Implements IService1.GetDataUsingDataContract
If composite Is Nothing Then Throw New ArgumentNullException("composite") End If If composite.BoolValue Then composite.StringValue &= "Suffix" End If Return composite End Function End Class
|
The
class just implements the contract interface and provides logic for
service operations working like any other .NET class. The content of the
.svc file is discussed later; for now let’s make some edits to the code
replacing the auto-generated one with custom implementation.
Implementing Custom Logic for the WCF Service
Rename the IService1.vb file to IBookService.vb and then switch to the code editor. Right-click the IService1 identifier and select Rename; finally provide the new IBookService identifier and click OK.
Visual Studio will prompt for confirmation and will rename the
instances in code as well. This is important to update all references
inside the project to the interface, including references inside the
.Svc file. Now delete the code for the CompositeType class and replace the entire code with the one shown in Listing 3.
Listing 3. Implementing Custom Contracts
<ServiceContract()> Public Interface IBookService
<OperationContract()> Function ValidateBook(ByVal bookToValidate As Book) As String
End Interface
<DataContract()> Public Class Book
<DataMember()> Public Property Title As String
<DataMember()> Public Property ISBN As String
<DataMember()> Public Property Author As String
<DataMember()> Public Property DatePublished As Date? End Class
|
The IBookService contract simply defines a ValidateBook method that will be invoked for validating a book. A single book is represented by the Book class, which exposes four self-explanatory properties. Now switch to the Service1 class and, following the steps described before, rename the Service1 identifier into BookService. Then replace the auto-generated code with the one shown in Listing 4.
Listing 4. Implementing the Service Logic
Imports System.Text.RegularExpressions Public Class BookService Implements IBookService
Private Const isbnPattern As String = _ "ISBN(?:-13)?:?\x20*(?=.{17}$)97(?:8|9)([ -])\d{1,5}\1\d{1,7}\1\d{1,6}\1\d$"
Public Function ValidateBook(ByVal bookToValidate As Book) As _ String Implements IBookService.ValidateBook
Dim isValidIsbn As Boolean = Regex.IsMatch(String.Concat("ISBN-13: ", bookToValidate.ISBN), isbnPattern)
If isValidIsbn = False Then Return "Invalid ISBN" End If
Dim isValidAuthor As Boolean = String.IsNullOrEmpty(bookToValidate.Author) If isValidAuthor = True Then Return "Author not specified" End If
Dim isValidTitle As Boolean = String.IsNullOrEmpty(bookToValidate.Title) If isValidTitle = True Then Return "Title not specified" End If
If bookToValidate.DatePublished Is Nothing Then Return "Book data is valid but date published was not specified" End If
Return "Valid book" End Function End Class
|
The code for the ValidateBook
method is quite simple. It makes use of a regular expression for
checking if the ISBN code is valid and then goes ahead checking for
valid properties in the Book class instance that must be validated.
Now right-click the BookService.svc file in Solution Explorer; select View in Browser.
In a few seconds the WCF service will be hosted by the ASP.NET
Development Server and will run inside the Web browser, as demonstrated
in Figure 2.
This test is required to
ensure that the service works correctly. Notice how information is
provided on how consuming the service is. The web page shows information
explaining that you should invoke the SvcUtil.exe command-line tool pointing to the wdsl metadata of the service.
SvcUtil is described in next
section; for the moment click the link available near SvcUtil.exe. By
doing so you access metadata offered by the WCF service, including
contracts and members, as reported in Figure 3.
Basically
client applications invoke service members passing through the service
metadata. The next section explains how you invoke service members
through a proxy class, but before going into that let’s take a look at
the BookService.svc file.
Right-click this file and select View Markup. The XHTML code for this file is the following:
<%@ ServiceHost Language="VB" Debug="true"
Service="BookService.BookService" CodeBehind="BookService.svc.vb" %>
This file defines the service entry point. Particularly it states that the BookService
class is the service entry point because it defines the real logic that
implements the contract. There is some other information such as the
programming language used and the code-behind the file, but the Service
tag is absolutely the most important. After this overview of the
service implementation, it’s time to consume the service from a client
application.