Click here to Skip to main content
15,881,812 members
Articles / Programming Languages / C#

Basic Step by Step WCF WebService

Rate me:
Please Sign up or sign in to vote.
4.78/5 (62 votes)
14 Feb 2016CPOL5 min read 263.3K   119   39
Basic steps in creating and consuming a simple WCF web service.

Introduction

In this article, I will be creating a simple Student Enrollment web service using WCF components from the ground up. This article does not use the WCF Project template in Visual Studio rather I will create this WCF web service using basic components that builds up the WCF technology. I will break down the components into separate discrete assemblies to give you a wider view of the big picture of WCF. Then, I will host this web service in a simple Console Application. Finally, I will consume the web service through a WPF application client.

Background

WCF is a unification of multiple technologies that were used in creating Distributed Applications which includes COM+, .NET Enterprise Services, MSMQ, .NET Remoting, Web services, etc. for communication. Hence, WCF is a vast topic to tackle in just one article. Because of this, you should be aware that this article only introduces you to a small part of the capability of WCF. However this article will try to demonstrate the most basic building blocks and architecture of WCF.

More of that, it would be much easier to grasp a topic if we can just create and test it, right? So let's dive into the code project!

Using the code

(Note: This project will use a Console Application to host the web service for simplicity. There are multiple ways to host a WCF web service. Please refer to other articles that discusses this part. Also note that this project uses Web Service Binding, specifically wsHTTPBinding. There are also many types of bindings to choose from that are not discussed in this article.)

First step - Define the WebService Interface

Image 1

Tip 1: In this article I am just creating one interface for our service but you can actually create as many interfaces as you want in your desired project.

Tip  2: Interfaces contain the signatures of the operations, messages and data that the client can use to communicate with the server.  

Image 2

  • Open Visual Studio 2010 and create a new project. Select Class Library project and name it BasicWCFWebService. Note: I am creating a Class Library for the WebService interface to decouple it from the service host logic and make it generally usable for both the client and host application.
  • A default class file Class1.cs is generated. Rename this file to IStudentEnrollmentService.cs. This file will contain the "Interface" that is exposed by this service. Also rename the first project to SchoolServiceInterfaces
  • In Solution Explorer, right click on the References folder and then click Add Reference. In the .NET tab, select System.ServiceModel and System.Runtime.Serialization assemblies, finally click the OK button.
    • System.ServiceModel contains the ServiceContractAttribute attribute definition
    • System.Runtime.Serialization contains the DataContractAttribute attribute definition
  • After adding the latter assembly references, include these in the code by adding using statements for both System.ServiceModel and System.Runtime.Serialization namespaces.

IStudentEnrollmentService.cs

C#
using System;
using System.Collections.Generic;
using System.Text;

using System.ServiceModel;
using System.Runtime.Serialization;

namespace SchoolServiceInterfaces 
{
    [ServiceContract]
    public interface IStudentEnrollmentService
    {
        [OperationContract]
        void EnrollStudent(Student s);

        [OperationContract]
        Student[] GetEnrolledStudents();
    }

    [DataContract]
    public class Student
    {
        private string name;

        [DataMember]
        public string StudentName
        {
            set { this.name = value; }
            get { return this.name; }
        }
    }
}

Second Step - Create a database "mock up" class

Create a new Class Library project and name it SchoolDatabase.cs.

Tip 3: This is just a mock up database project. You can create or use the real database objects on your real project. This is the reason why we created a separate project for the database so that we can emulate a real world database architecture. Remember that a database is a separate entity and not bound to our project.

Image 3

StudentDatabase.cs

C#
using System;
using System.Collections.Generic;
using System.Text;

namespace SchoolDatabase
{
    public class StudentDatabase
    {
        private static List<string> studentData = new List<string>();

        public void AddStudent(string studentName)
        {
            studentData.Add(studentName);
        }

        public List<string> GetStudentList()
        {
            return studentData;
        }
    }
}

Third step - Implement the web service interface

Image 4

  • Create a new Class Library project and name it SchoolServices and rename Class1.cs to StudentEnrollmentService.cs. Then, add references to the SchoolDatabase and SchoolServiceInterfaces projects. To do this, right click on the References folder in the SchoolServices project then on the "Project" tab, select the SchoolDatabase and StudentServiceInterfaces projects.
  • Implement the IStudentEnrollmentService interface and use the StudentDatabase class to store student information.

StudentEnrollmentService.cs

C#
using System;
using System.Collections.Generic;
using System.Text;

using SchoolServiceInterfaces;
using SchoolDatabase;

namespace SchoolServices
{
    public class StudentEnrollmentService : IStudentEnrollmentService
    {
        public void EnrollStudent(Student s)
        {
            StudentDatabase sd = new StudentDatabase();
            sd.AddStudent(s.StudentName);
        }

        public Student[] GetEnrolledStudents()
        {
            StudentDatabase sd = new StudentDatabase();
            List<string>studentList = sd.GetStudentList();
            Student[] studentArray = new Student[studentList.Count];
            for (int i = 0; i < studentList.Count; i++)
            {
                Student s = new Student();
                s.StudentName = studentList[i];
                studentArray[i] = s;
            }
            return studentArray;
        }
    }
}

Fourth step - Host the web service

  • To run the web service we must host it. In this article we will just use a simple Console Application to host our web service.
  • To do this, create a new Console Application project and name it SchoolServiceHost. Then add references to .NET System.ServiceModel and to our projects SchoolServices and SchoolServiceInterfacesSystem.ServiceModel is a .Net component that contains the base mechanism of a .Net web service, in this case, to create a Service host by using ServiceHost. I suggest you read more about System.ServiceModel namespace.

Image 5

Program.cs

XML
using System;
using System.Collections.Generic;
using System.Text;

using System.ServiceModel;
using SchoolServices;

namespace SchoolServiceHost
{
    class Program
    {
        static ServiceHost host = null;

        static void StartService()
        {
            host = new ServiceHost(typeof(StudentEnrollmentService)); 
	    /***********
	     * if you don't want to use App.Config for the web service host, 
             * just uncomment below:
	     ***********
             host.AddServiceEndpoint(new ServiceEndpoint(
             ContractDescription.GetContract(typeof(IStudentEnrollmentService)),
             new WSHttpBinding(), 
             new EndpointAddress("http://localhost:8732/awesomeschoolservice"))); 
	     **********/
            host.Open();
        }

        static void CloseService()
        {
            if (host.State != CommunicationState.Closed)
            {
                host.Close();
            }
        }

        static void Main(string[] args)
        {
            StartService();

            Console.WriteLine("Student Enrollment Service is running....");
            Console.ReadKey();

            CloseService();
        }
    }
} 

Add App.config file to the SchoolServiceHost project. This will contain the ABC information of our WCF web service which are:

  • "A" for "Address" - where to access the service. This defines the endpoint information where the service is located or accessible.
  • "B" for "Binding" - how to access the service. This defines the transport protocol that should be used to access this service.
  • "C" for "Contract" - what to access in the service. This defines the services offered by this web service.

Image 6

App.config

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- Server Configuration -->
  <system.serviceModel>
    <services>
      <service name="SchoolServices.StudentEnrollmentService">
        <endpoint 
		address="http://localhost:8732/awesomeschoolservice" 
		binding="wsHttpBinding" 
		contract="SchoolServiceInterfaces.IStudentEnrollmentService" />
      </service>
    </services>
  </system.serviceModel>
</configuration> 

Fifth step - Consuming the web service through a WPF client

Add a new WPF Application project and name it SchoolServiceClient. Then add references to System.ServiceModel and SchoolServiceInterfaces.

Image 7

Tip 4: Client only needs to know the signature of our service, it doesn't need to know the implementation or how the service implemented those services that is why we will only add the reference of SchoolServiceInterfaces which contains the contract of the web service we are interested to. System.ServiceModel is a .Net component that contains the base mechanism of a .Net web service, in this case, to create a Service client by using ChannelFactory. I suggest you read more about System.ServiceModel namespace.

MainWindow.xaml

Image 8

XML
<Window x:Class="SchoolServiceClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="296" Width="293">
    <Grid>
        <Button Content="Enroll" Height="23" HorizontalAlignment="Left" Margin="184,12,0,0" 
		Name="enrollBtn" VerticalAlignment="Top" Width="75" Click="enrollBtn_Click" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="studentNameTxt" 
		VerticalAlignment="Top" Width="152" />
        <Button Content="Get Enrolled Students" Height="23" HorizontalAlignment="Left" Margin="136,222,0,0" 
		Name="getEnrollBtn" VerticalAlignment="Top" Width="123" Click="getEnrollBtn_Click" />
        <TextBox Height="165" HorizontalAlignment="Left" Margin="12,51,0,0" Name="enrolledTxt" 
		VerticalAlignment="Top" Width="247" />
    </Grid>
</Window>

MainWindow.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.ServiceModel;
//contains the signature(message, data, operation)
//of the web service
using SchoolServiceInterface;

namespace SchoolServiceClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void enrollBtn_Click(object sender, RoutedEventArgs e)
        {
            if (studentNameTxt.Text == "") return;

            using (ChannelFactory<IStudentEnrollmentService> schoolServiceProxy = 
			new ChannelFactory<IStudentEnrollmentService>("MyStudentEnrollmentServiceEndpoint"))
            {
                schoolServiceProxy.Open();
                IStudentEnrollmentService schoolEnrollmentService = schoolServiceProxy.CreateChannel();
                Student s = new Student();
                s.StudentName = studentNameTxt.Text;
                schoolEnrollmentService.EnrollStudent(s);
                schoolServiceProxy.Close();
            }

            studentNameTxt.Text = "";
        }

        private void getEnrollBtn_Click(object sender, RoutedEventArgs e)
        {
            enrolledTxt.Text = "";
            using (ChannelFactory<IStudentEnrollmentService> schoolServiceProxy = 
			new ChannelFactory<IStudentEnrollmentService>("MyStudentEnrollmentServiceEndpoint"))
            {
                schoolServiceProxy.Open();
                IStudentEnrollmentService schoolEnrollmentService = schoolServiceProxy.CreateChannel();
                Student[] enrolledStudents = schoolEnrollmentService.GetEnrolledStudents();
                foreach (Student s in enrolledStudents)
                {
                    enrolledTxt.AppendText(s.StudentName + "\n");
                }
                schoolServiceProxy.Close();
            }
        }
    }
}

App.config

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- Client Configuration -->
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IStudentEnrollmentService" />
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8732/awesomeschoolservice"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IStudentEnrollmentService"
          contract="SchoolServiceInterfaces.IStudentEnrollmentService" name="MyStudentEnrollmentServiceEndpoint">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

Sixth Step - Run and test the web service

  • Build the solution, then go to the output directories of SchoolServiceHost and SchoolServiceClient. First run SchoolServiceHost.exe, then SchoolServiceClient.exe, respectively.

Image 9

Points of interest

Decoupling components greatly improves maintainability, scalability, and stability of an application. This topic demonstrates the most basic parts of a WCF application rather than using a template. Building these small parts gives you flexibility and an in-depth understanding of its underlying technologies. You should now be able to create more advanced WCF applications using the very basic understanding of its architecture and its building blocks. 

Your feedback is always welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Philippines Philippines
Raw tools of C++ and highly sophisticated C#.Net framework architecture is picture-perfect!

Comments and Discussions

 
QuestionPhenomenal contribution Pin
Member 1483866020-May-20 7:47
Member 1483866020-May-20 7:47 
QuestionError while hosting the service Pin
Snehlata Shaw9-Feb-17 2:32
Snehlata Shaw9-Feb-17 2:32 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun3-Mar-16 1:37
Humayun Kabir Mamun3-Mar-16 1:37 
QuestionError Pin
Sarathkumar Palanisamy26-Aug-15 23:50
Sarathkumar Palanisamy26-Aug-15 23:50 
AnswerThe most efficient tutorial so far!!! Pin
Douglas AE24-May-15 6:35
Douglas AE24-May-15 6:35 
QuestionExcellent refresher tutorial Pin
ldanoski15-May-15 9:54
ldanoski15-May-15 9:54 
QuestionTutorial fails at MainWindow which is skipped. Impossible to finish the project. Pin
jsharbour12-Feb-15 9:03
jsharbour12-Feb-15 9:03 
QuestionC Pin
Member 1139431726-Jan-15 4:08
Member 1139431726-Jan-15 4:08 
SuggestionResolve SchoolServiceHost Issue Pin
Dina Hess6-Nov-14 4:58
Dina Hess6-Nov-14 4:58 
QuestionGreat article. Here are some additional tips Pin
KiethBiasillo5-Sep-14 19:37
KiethBiasillo5-Sep-14 19:37 
QuestionThanks Pin
my_magic25-Aug-14 0:11
my_magic25-Aug-14 0:11 
GeneralThank you Pin
Member 10367186 (Pratheek)29-Jun-14 19:28
Member 10367186 (Pratheek)29-Jun-14 19:28 
QuestionError on Program.cs in SchoolServiceHost ... Pin
juno1684-Jun-14 6:48
juno1684-Jun-14 6:48 
AnswerRe: Error on Program.cs in SchoolServiceHost ... Pin
Member 1091885529-Jul-14 4:26
Member 1091885529-Jul-14 4:26 
QuestionGetting Error - Please Guide Pin
Madhu.Chande21-Mar-14 2:10
Madhu.Chande21-Mar-14 2:10 
AnswerRe: Getting Error - Please Guide Pin
sarath rachuri2-Nov-14 22:54
sarath rachuri2-Nov-14 22:54 
QuestionWSDL Pin
carmiFr-117-Mar-14 10:50
carmiFr-117-Mar-14 10:50 
QuestionGuys Help Me I got Error Pin
Dharmaprabhu.M7-Mar-14 2:05
Dharmaprabhu.M7-Mar-14 2:05 
QuestionHelp me : I got some error Pin
Dharmaprabhu.M7-Mar-14 2:01
Dharmaprabhu.M7-Mar-14 2:01 
AnswerRe: Help me : I got some error Pin
Dharmaprabhu.M20-Mar-14 2:48
Dharmaprabhu.M20-Mar-14 2:48 
Question.Net Framework Pin
Member 106464235-Mar-14 11:21
Member 106464235-Mar-14 11:21 
AnswerRe: .Net Framework Pin
carmiFr-117-Mar-14 10:53
carmiFr-117-Mar-14 10:53 
GeneralRe: .Net Framework Pin
juno1684-Jun-14 6:52
juno1684-Jun-14 6:52 
QuestionError when running "SchoolServiceHost.exe" Pin
nemoze4-Jan-14 13:09
nemoze4-Jan-14 13:09 
GeneralMy vote of 5 Pin
mvrene6-Nov-13 14:12
mvrene6-Nov-13 14:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.