Developing a WCF Service Library and Hosting it as WCF Web Service Using VS2K8

In this article, we will focus on developing a Windows Communication Foundation (WCF) library, turning it to a WCF web service, hosting it on an IIS web server and finally test it by developing a simple WCF client using Windows Forms. This article can serve as an excellent walkthrough resource for beginners.


A downloadable zip file is available for this article.

WPF, WCF, WWF and Silverlight are the next generation components from Microsoft which revolutionize the current .NET Framework with great new and innovative architectures. I will not look into the details of the architectures of these new components as Microsoft has already added great content on the subject on its MSDN.

Please be aware that we are not directly creating a WCF web service in this article. In fact, Visual Studio 2008 beta 2 includes two templates, "WCF Service Application" and "WCF Service Library." "WCF Service Application” itself is a direct web service application relying on WCF technology (which is similar to the ASP.NET web service development). "WCF Service Library" on the other hand is a compiled component which can be deployed as a web service or a Windows service or even as a part of a customized hosting application. 

In this article, we will create a WCF service library (simply a compiled WCF library), turn it into a WCF web service, host it on IIS and finally access it using a WCF client. As we would like to create a WCF service library and host it as a web service on IIS, "web.config" will be necessary during deployment.

If you have not configured IIS after installing Visual Studio 2008 beta 2, it is highly advised that you run the following (for proper mappings and automated IIS configuration):

ServiceModelReg.exe /i /x

To make this article simple, I added the "emp" to the Northwind database.

The entire source code for this article is available in the form of a downloadable zip file. The solution was developed using Microsoft Visual Studio 2008 Beta 2 on Microsoft Windows Server 2003 Enterprise Edition. I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems with execution. 

{mospagebreak title=Creating a Windows Communication Foundation (WCF) Service Library}

The following are the steps necessary to create a WCF Service Library: 
  • Open Microsoft Visual Studio 2008 Beta 2.
  • Go to File || New Project.  
  • In the "New Project" dialog box, open "Visual Basic" project types and select WCF. The respective templates for WCF will be shown on the right side.
  • Select the "WCF Service Library" template.
  • Provide "WCFSampleService" as the name and provide the proper path as the location.
  • Make sure that ".NET Framework 3.5" is selected at the top.  
  • Once everything looks like the following (fig 01), click OK.
  • Rename "IService1.vb" to "IEmpService.vb."
  • Rename "Service1.vb" to "EmpService.vb."
  • Add a reference to "System.Configuration" as shown below (fig 02).

 

Figure 01

Figure 02

Creating a Windows Communication Foundation (WCF) Service Library: source code

Once the project is created (as shown above), modify "IEmpService.vb" to match the following:

 <ServiceContract()> _

  Public Interface IEmpService

<OperationContract()> _

  Function GetNames() As List(Of String)

<OperationContract()> _

  Function GetEmployeeInfo(ByVal EmpNo As Integer) As Employee

End Interface

<DataContract()> _

Public Class Employee

  Private _Empno As Integer

  Private _Ename As String

  Private _Sal As Double

  Private _Deptno As Integer

<DataMember()> _

  Public Property Empno() As Integer

   Get

    Return _Empno

   End Get

    Set(ByVal value As Integer)

     _Empno = value

    End Set

End Property

<DataMember()> _

  Public Property Ename() As String

   Get

    Return _Ename

   End Get

    Set(ByVal value As String)

     _Ename = value

    End Set

End Property

<DataMember()> _

  Public Property Sal() As Double

   Get

    Return _Sal

   End Get

    Set(ByVal value As Double)

     _Sal = value

    End Set

End Property

<DataMember()> _

  Public Property Deptno() As Integer

   Get

    Return _Deptno

   End Get

    Set(ByVal value As Integer)

     _Deptno = value

    End Set

End Property

End Class

Modify "EmpService.vb" to match the following:

Imports System.Data.SqlClient

Imports System.Data

Imports System.Configuration

Public Class EmpService

  Implements IEmpService

Public Function GetEmployeeInfo(ByVal EmpNo As Integer) As Employee Implements IEmpService.GetEmployeeInfo

Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings("cnNorthwind").ConnectionString)

Using cmd As New SqlCommand("SELECT empno,ename,sal,deptno FROM dbo.emp WHERE empno=" & EmpNo, cn)

  cmd.Connection.Open()

   Using rdr As SqlDataReader = cmd.ExecuteReader

    If rdr.Read() Then

Return New Employee With {.Empno = rdr(rdr.GetOrdinal("Empno")), .Ename = rdr(rdr.GetOrdinal("Ename")) & "", .Sal = rdr(rdr.GetOrdinal("sal")) & "", .Deptno = rdr(rdr.GetOrdinal("Deptno")) & ""}

   Else

     Return Nothing

   End If

End Using

   cmd.Connection.Close()

  End Using

 End Using

End Function

Public Function GetNames() As System.Collections.Generic.List(Of String) Implements IEmpService.GetNames

  Dim EmployeeNames As New List(Of String)

Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings("cnNorthwind").ConnectionString)

   Using cmd As New SqlCommand("SELECT ename FROM dbo.emp", cn)

  cmd.Connection.Open()

   Using rdr As SqlDataReader = cmd.ExecuteReader

    If rdr.HasRows Then

     While rdr.Read

      EmployeeNames.Add(rdr(rdr.GetOrdinal("ename")))

     End While

      Return EmployeeNames

     Else

      Return Nothing

     End If

End Using

   cmd.Connection.Close()

  End Using

 End Using

End Function

End Class

{mospagebreak title=Creating a Windows Communication Foundation (WCF) Service Library: application configuration}

As we created a WCF Service Library (instead of a WCF Service Application), Visual Studio adds an "app.config" file (as opposed to a "web.config" as it would with a WCF Service Application) to the solution. Modify "app.config" to match the following: 
 

<system.serviceModel>

<services>

<service name="WCFSampleService.EmpService" behaviorConfiguration="WCFSampleService.EmpServiceBehavior">

<host>

<baseAddresses>

<add baseAddress = "http://localhost/EmpService" />

</baseAddresses>

</host>

<!– Service Endpoints –>

<!– Unless fully qualified, address is relative to base address supplied above –>

<endpoint address ="" binding="wsHttpBinding" contract="WCFSampleService.IEmpService" />

<!– Metadata Endpoints –>

<!– The Metadata Exchange endpoint is used by the service to describe itself to clients. –>

<!– This endpoint does not use a secure binding and should be secured or removed before deployment –>

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="WCFSampleService.EmpServiceBehavior">

<!– 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="True" />

</behavior>

</serviceBehaviors>

</behaviors>

<bindings>

<wsHttpBinding>

<binding name="SampleServiceBinding">

<security/>

</binding>

</wsHttpBinding>

</bindings>

</system.serviceModel>

Turning a Windows Communication Foundation (WCF) Service Library into a WCF Service Application (web service) 

In the previous section, we worked with "app.config" to configure the WCF Service Library. To turn a WCF service library into WCF service application (or WCF Web Service), the first step is to add "web.config" to the solution and make modifications to the file to match the following (look for the "added by me" comments):  

<?xml version="1.0"?>

<configuration>


<configSections>

<section name="WorkflowRuntime" type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

</configSections>

<WorkflowRuntime Name="WorkflowServiceContainer">

<Services>

<add type="System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

<add type="System.Workflow.Runtime.Hosting.
DefaultWorkflowCommitWorkBatchService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

</Services>

</WorkflowRuntime>

<appSettings/>

<!– added by me–>

<connectionStrings>

<add name="cnNorthwind" connectionString="Database=Northwind;Server=(local)sql2k5;user id=sa;password=eXpress2005"/>

</connectionStrings>

<!– added by me –>

<system.serviceModel>

<services>

<service name="WCFSampleService.EmpService" behaviorConfiguration="WCFSampleService.EmpServiceBehavior">

<host>

<baseAddresses>

<add baseAddress = "http://localhost/EmpService" />

</baseAddresses>

</host>

<endpoint address ="" binding="wsHttpBinding" contract="WCFSampleService.IEmpService" />

<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="WCFSampleService.EmpServiceBehavior">

<serviceMetadata httpGetEnabled="True"/>

<serviceDebug includeExceptionDetailInFaults="True" />

</behavior>

</serviceBehaviors>

</behaviors>

<bindings>

<wsHttpBinding>

<binding name="SampleServiceBinding">

<security/>

</binding>

</wsHttpBinding>

</bindings>

</system.serviceModel>

<system.web>

<compilation debug="false"/>

<authentication mode="Windows"/>

<httpModules>

<add type="System.Workflow.Runtime.Hosting.WorkflowWebHostingModule, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="WorkflowHost"/>

</httpModules>

</system.web>

</configuration>

Once the "web.config" is added, the second step is to add an "EmpService.svc" file to the solution. Just add a text file (using "add new item") named "EmpService.svc" as shown below (fig 03).

Figure 03

Copy the following to "EmpService.svc."

<%@ ServiceHost Service="WCFSampleService.EmpService" %>

<%@ Assembly Name="WCFSampleService" %>


Once the service file is added, the final step is to change the "build output path" of the project to "bin" (as shown below in fig 04):

Figure 04

Close all tabbed windows of Visual Studio (I suspect it could be a bug as it could not compile properly on my machine, without closing all windows) and build the solution.

{mospagebreak title=Deploying and Hosting a WCF Service application (WCF web service)}

Once the solution is built successfully, we need to deploy/host it on IIS. Let us start with creating a Virtual Directory in IIS to host our solution. Go through the following steps to create the same in the simplest manner:

  • Go to the application folder (not the solution folder), right click on it and then click on "Properties" (fig 05).  
  • Switch to the "Security" tab and make sure that all privileges are provided for both the "ASP.NET machine account" and the "NETWORK SERVICE" accounts (fig 06).
  • Switch to "Web Sharing" and click on "Share this folder" (fig 07). 
  • Accept the "default alias" ("WCFSampleService") as follows (fig 08) and click OK twice (to apply all the properties).

Figure 05

Figure 06

Figure 07

Figure 08

Deploying and Hosting WCF Service application (WCF web service), continued  

Open IIS (Start || Administrative Tools || Internet Information Services Manager), and then open "Default Web Site." You should see the "WCFSampleService" configured as a web application.

  • Right click on "WCFSampleService" and go to "Properties" (fig 09).
  • Switch to the "ASP.NET" tab and select the ASP.NET version "2.0.50727" (fig 10).
  • Switch to "Directory Security," click on "Edit" of "Authentication and Access control," make "Enable anonymous access" checked (fig 11) and click OK twice to apply all the properties.
  • If the solution is configured, built and hosted properly, you should be able to access the web service from the URL http://localhost/WCFSampleService/EmpService.svc and the output should look like the following (fig 12).

 

Figure 09

Figure 10

Figure 11

Figure 12

{mospagebreak title=Testing the WCF Web Service: creating the WCF Client using Windows Forms}

To test the WCF web service created in previous sections, we need to develop a WCF client. In this case, for simplicity, I would like to work with Windows Forms.

Open a new Visual Studio environment, create a new project, select "Windows Forms Application" as the template, provide the name "WCFSampleClient" and hit OK (fig 13). 

Figure 13

Design a form which looks like the following (fig 14):

Figure 14

Add a reference to WCF Service by right clicking on project and selecting "Add Service Reference" (fig 15). 
 

Figure 15

Provide the previously created WCF Web Service URL as http://iisservername/WCFSampleService/EmpService.svc?wsdl and click "Go." Once it is found, designate the namespace as "EmpService" and hit OK (fig 16). 

Figure 16

Testing the WCF Web Service: source code 

For the Windows form previously created, make modifications to the existing code so it matches with the following:

Imports System.ServiceModel

Public Class Form1

Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click

Dim proxy As New EmpService.EmpServiceClient("WSHttpBinding_IEmpService")

Dim objEmp As EmpService.Employee = proxy.GetEmployeeInfo(Me.txtEmpno.Text)

proxy.Close()

With objEmp

Me.txtEname.Text = .Ename

Me.txtSal.Text = .Sal

Me.txtDeptno.Text = .Deptno

End With

End Sub

Private Sub btnGetAllNames_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetAllNames.Click

Dim proxy As New EmpService.EmpServiceClient("WSHttpBinding_IEmpService")

Me.lstNames.DataSource = proxy.GetNames

proxy.Close()

End Sub

End Class

Finally, hit F5 to execute and test the application (which accesses and retrieves information from the WCF web service hosted earlier). If everything works fine, you should be able see the output as follows (fig 17):  

Figure 17

I hope you enjoyed the article and any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

10 thoughts on “Developing a WCF Service Library and Hosting it as WCF Web Service Using VS2K8

  1. Hello guys,

    This is my first part for the series of articles on WCF. This article shows you the step by step process in developing a WCF Service Library and converting it to a WCF Web Service and finally host it in IIS.

    Hope you enjoy the article.

    thanks
    Jag

  2. Hello,
    I created a WCF service in VS2008 and when I try to browse the service in IIS 5.1, i get an error such as:

    Operation ‘GetNextSubUnitNumber’ in contract ‘ICupeLocalService’ uses a MessageContract that has SOAP headers. SOAP headers are not supported by the None MessageVersion.

    BUT, if I browse the service from within VS2008, its all fine and I get the “home” page of the service as per your article (Figure 12).

    Not sure why it work via VS2008 but not via IIS v5.1
    Any ideas on what I am missing??

  3. Great article! I just start doing this and learned quite a lot. I have one question?

    Why you use WCF Service Library instead of simple create a (Web) WCF Service Application?

    What I am trying to do is an N-Tier Data Application like the one from MSDN (http://msdn.microsoft.com/en-u…. I followed the workthrough but I want the service on a webserver. Your article should solve my problem. But I thought create a web WCF Service application will be easier.

    Thanks,

    John

  4. Hi when browse the WCF webservice i am getting the following error:

    “The contract name ‘IGeometryService ‘ could not be found in the list of contracts implemented by the service ‘GeometryService'”

    Kindly help related to this.

  5. First off, thanks for the article.

    I was wondering, though, just how hard it would be to change things so that I can have any number of web services, all of which expose the same interface. Only one of these services would be loaded (hosted?) by a windows forms application, who would use the common interface to get information back from the (dynamically hosted) service.

    The service selection would be done at run-time by a user, and the windows forms application would use the selection to load the appropriate service.

    From what I see in your example, it is closer to an example of ‘early binding’, while what I’m describing is an example of ‘late binding’. That late binding, coupled with he common interface, allow the hosting Windows forms application to use any number of services. (each of which may supply something a little different than the other)

    Think of the (WCF application) ‘services’ as ‘refrigerators’. Each offers the same interface, even though there may be many available. Deciding which to use (host) gives you the selection offered by that refer.

    How tough? Know of any examples?

    Thanks!
    Pat

  6. Hi,
    Nice Article.
    I have one query, when we deploy the application WebService and client(winform)
    that time how we know which URL is access or need to add Add Service reference to client because, if we declare like address : http://localhost/MyService/Abc.svc and if deploy to client’s machine and also deploy/setup your client(i.e buildable executable) then how can we re-configure URL

    Thanks

  7. I followed the above steps, however; when I tried calling the service I get the following message, “
    The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘Negotiate,NTLM’.”

    On the client end I made changes to the app.config. It now looks like this.







    I also changed the Security mode=None in the wsHttpBinding section of the client and the service.

    Please help.

  8. This is great information about WCF service provider. This blog provide good topic wise information for web hosting service. I like this impressive posted article.

[gp-comments width="770" linklove="off" ]