Creating, Hosting and Consuming Simple Windows Communication Service (WCF)

Overview
 
In this article we will create a simple WCF service. We will host it in a simple console application. We will then consume this service in Windows Client. After completion of this 
article you will understand the following:

  1. Defining Contracts for WCF service.
  2. Using basicHttpBinding and wsHttpBinding with differences.
  3. Creating proxy using Visual Studio 2008 IDE.
  4. Creating proxy client using WCF APIs.

Creating the WCF Service, Writing the Host and Consuming it in a Client
 
Task 1: Open Visual Studio 2008 and create a blank solution, name it "WCF_ServiceHostClient". In this solution add a new class library project; name it "WCF_Service". (Note: Visual Studio 2008 already provides WCF templates; once you understands the basics, you can use this template for all other projects).
 
Task 2: In the "WCF_Service" project add a reference for the following namespaces:

  • System.ServiceModel.

Task 3: In this project, add a new interface, name it "IService". This interface will expose "ServiceContract" and "OperationContract" as below:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Data;

using System.ServiceModel;

 

namespace WCF_Service

{

    [ServiceContract]

    public interface IService

    {

        [OperationContract]

        int Add(int x, int y);

        [OperationContract]

        DataSet GetData(string dbName, string tbName);

    }

}

Task 4: In "WCF_Service", you have "Class1.cs", rename this as "CService.cs". In this file write the following code:
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Data;

using System.Data.SqlClient;

 

namespace WCF_Service

{

    public class CService : IService

    {

        #region IService Members

        public int Add(int x, int y)

        {

            return x + y;

        }

        public DataSet GetData(string dbName, string tbName)

        {

            SqlConnection Conn = new SqlConnection("Data Source=.;Initial Catalog=" + dbName + ";Integrated Security=SSPI");

            SqlDataAdapter AdTable = new SqlDataAdapter("Select * from " + tbName, Conn);

            DataSet Ds = new DataSet(); AdTable.Fill(Ds, tbName);

            return Ds;

        }

        #endregion

    }

}
 
Task 5: Build the project and ensure that it is error free.
 
Task 6: In the same solution add a new console application, name it "WCF_ConsoleHost". This console application will act as HOST for the WCF service. In this project add a reference of the following:

  • System.ServiceModel.
  • WCF_Service.dll. (This is the WCF service reference.)

Task 7: Open "Program.cs" and write the following code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel;

 

namespace WCF_ConsoleHost

{

    class Program

    {

        static void Main(string[] args)

        {

            ServiceHost Host = new ServiceHost(typeof(WCF_Service.CService)

            );

            Host.Open();

            Console.WriteLine("Service Started..."); Console.ReadLine();

            Host.Close(); Console.ReadLine();

        }

    }

}

The the code above, create an instance of the "ServiceHost" class, this class provides hosting for the WCF service.
 
Task 8: In the host project add a "App.Config" file. This file contains hosting configuration for the WCF service. This defines the hosting base address and binding used by the WCF service and the behavior of the service.
 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <services>

      <!--name:Full Qualify Path of Service Class-->

      <service name="WCF_Service.CService"

behaviorConfiguration="ServeBehave">

        <!--Host Address, i.e Repository-->

        <host>

          <baseAddresses>

            <add

baseAddress="http://localhost:9012/MyServ"/>

          </baseAddresses>

        </host>

        <!--Endpoint

Address: Absolute

Binding: Protocol to be used Contract:Schema-->

        <endpoint address=""

        binding="basicHttpBinding"

        contract="WCF_Service.IService"/>

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior name="ServeBehave">

          <serviceMetadata httpGetEnabled="True"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>


The preceding configuration states that the WCF service uses "basicHttpBinding". This binding is not secure by default, this binding transfers the data in plain text form. This data can be seen when the service messages are traced.
 
Task 9: Build the console project; ensure it is error free.
 
Task 10: To test the service, the host must be running. Right-click on the solution and select
"multiple startup projects" and select "WCF_ConsoleHost" as in the following:


Windows-Communication-Service-1.jpg

Task 11: Run the application, you will get the following output:

Windows-Communication-Service-2.jpg

Task 12: Keep pressing the "Ctrl" button and click on the URL from the App.Config, you will get the following output indicating that the service is running:

Windows-Communication-Service-3.jpg

Task 13: Stop the host.
 
Task 14: In the solution, add a new Windows project, name it "WinForm_WCFClinet". Design the client project as below:

Windows-Communication-Service-4.jpg

Task 15: Now to create a proxy in the client application, the service must be running, so run the console application using "Ctrl+F5". And then right-click on the references of the client project and select "Add Service Reference" as below:

Windows-Communication-Service-5.jpg

Task 16:
When you click the "OK" button, you will get the "MyRef" stub that will have the proxy class, this class will be inherited from the "ClientBase<T>" class. The client application will have an "App.Config" file. If you see the configuration file then you will see it contains "basicHttpBinding". The most important part in this config file is "maxRecivedMessageSize=65536" and "transferMode=Buffered", then the security mode is set to "None" as below:
 

<security mode="None">

  <transport clientCredentialType="None" proxyCredentialType="None"

  realm="">

    <extendedProtectionPolicy 

policyEnforcement="Never" />

  </transport> 

  <message clientCredentialType="UserName" algorithmSuite="Default" />

</security>

Task 17: Open Form1.cs and write the following code:
 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

 

namespace WinForm_WCFClinet

{

    public partial class Form1 : Form

    {

        MyRef.ServiceClient Proxy;

        public Form1()

        {

            InitializeComponent();

        }

        private void btnAdd_Click(object sender, EventArgs e)

        {

            MessageBox.Show(Proxy.Add(2, 4).ToString());

        }

        private void btnGetdadat_Click(object sender, EventArgs e)

        {

            DataSet Ds = Proxy.GetData(txtdbname.Text, txttbname.Text); dgtable.DataSource = Ds.Tables[txttbname.Text];

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            Proxy = new WinForm_WCFClinet.MyRef.ServiceClient();

        }

    }

}

Task 18: Right-click on the solution and select "Multiple Startup Projects", and start the Console Host project followed by the Client project as below:

Windows-Communication-Service-6.jpg

Task 19: Run the application, wait for the console window to display the message "Service Started..." and click on the "Add" button. You will get the Add MessageBox with add result. In the TextBox below "Database" enter database name, from which you want to get the data and in the TextBox below the Table Name enter the table name and click on the "Get Data" button, you will get the following result:

Windows-Communication-Service-7.jpg

Note: Create a database named "Company" and create the following tables:
 

CREATE TABLE [dbo].[Department](

[DeptNo] [int] NOT NULL,

[Dname] [varchar](50) NOT NULL,

[Location] [varchar](50) NOT NULL,

CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED

(

[DeptNo] ASC

)WITH (PAD_INDEX

= OFF, STATISTICS_NORECOMPUTE

= OFF, IGNORE_DUP_KEY = OFF,

ALLOW_ROW_LOCKS

= ON, ALLOW_PAGE_LOCKS

= ON) ON [PRIMARY]

) ON [PRIMARY]

 

CREATE TABLE [dbo].[Employee](

[EmpNo] [int] NOT NULL,

[EmpName] [varchar](50) NOT NULL,

[Salary] [int] NOT NULL,

[DeptNo] [int] NOT NULL,

CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED

(

[EmpNo] ASC

)WITH (PAD_INDEX

= OFF, STATISTICS_NORECOMPUTE

= OFF, IGNORE_DUP_KEY = OFF,

ALLOW_ROW_LOCKS

= ON, ALLOW_PAGE_LOCKS

= ON) ON [PRIMARY]

) ON [PRIMARY]