Click here to Skip to main content
11,435,451 members (64,445 online)
Click here to Skip to main content

Tagged as

Basic Step by Step WCF WebService

, 16 Oct 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
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

  • 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
  • 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.  

  • 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

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.

StudentDatabase.cs

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

  • 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

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 SchoolServiceInterfaces

Program.cs

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.

App.config

<?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, SchoolServiceInterfaces, and SchoolServices.

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. 

MainWindow.xaml

<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 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.

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)

Share

About the Author

yani papi

Philippines Philippines
Adrian T. Visarra is a professional software engineer. He started his professional career as a software engineer on August 2010. He is currently working in a company that specializes in Multi-Functional Products as a Senior Systems Engineer based in the Philippines. He is also a huge Microsoft .Net Framework enthusiast but also have wide experience and interest with Linux and Open Source Web Development software.

Comments and Discussions

 
QuestionTutorial fails at MainWindow which is skipped. Impossible to finish the project. Pin
jsharbour12-Feb-15 10:03
memberjsharbour12-Feb-15 10:03 
QuestionC Pin
Member 1139431726-Jan-15 5:08
memberMember 1139431726-Jan-15 5:08 
SuggestionResolve SchoolServiceHost Issue Pin
Dina Hess6-Nov-14 5:58
memberDina Hess6-Nov-14 5:58 
QuestionGreat article. Here are some additional tips Pin
KiethBiasillo5-Sep-14 20:37
memberKiethBiasillo5-Sep-14 20:37 
QuestionThanks Pin
my_magic25-Aug-14 1:11
membermy_magic25-Aug-14 1:11 
GeneralThank you Pin
Member 10367186 (Pratheek)29-Jun-14 20:28
memberMember 10367186 (Pratheek)29-Jun-14 20:28 
QuestionError on Program.cs in SchoolServiceHost ... Pin
Member 104575434-Jun-14 7:48
memberMember 104575434-Jun-14 7:48 
AnswerRe: Error on Program.cs in SchoolServiceHost ... Pin
Member 1091885529-Jul-14 5:26
memberMember 1091885529-Jul-14 5:26 
QuestionGetting Error - Please Guide Pin
MadDevelopers21-Mar-14 3:10
memberMadDevelopers21-Mar-14 3:10 
AnswerRe: Getting Error - Please Guide Pin
sarath rachuri2-Nov-14 23:54
membersarath rachuri2-Nov-14 23:54 
QuestionWSDL Pin
carmiFr-117-Mar-14 11:50
membercarmiFr-117-Mar-14 11:50 
QuestionGuys Help Me I got Error Pin
Dharmaprabhu.M7-Mar-14 3:05
memberDharmaprabhu.M7-Mar-14 3:05 
QuestionHelp me : I got some error Pin
Dharmaprabhu.M7-Mar-14 3:01
memberDharmaprabhu.M7-Mar-14 3:01 
AnswerRe: Help me : I got some error Pin
Dharmaprabhu.M20-Mar-14 3:48
memberDharmaprabhu.M20-Mar-14 3:48 
Question.Net Framework Pin
Member 106464235-Mar-14 12:21
memberMember 106464235-Mar-14 12:21 
AnswerRe: .Net Framework Pin
carmiFr-117-Mar-14 11:53
membercarmiFr-117-Mar-14 11:53 
GeneralRe: .Net Framework Pin
Member 104575434-Jun-14 7:52
memberMember 104575434-Jun-14 7:52 
QuestionError when running "SchoolServiceHost.exe" Pin
nemoze4-Jan-14 14:09
membernemoze4-Jan-14 14:09 
GeneralMy vote of 5 Pin
mvrene6-Nov-13 15:12
membermvrene6-Nov-13 15:12 
QuestionNice job Pin
Member 963308418-Oct-13 13:09
memberMember 963308418-Oct-13 13:09 
AnswerRe: Nice job Pin
yani papi18-Oct-13 21:24
memberyani papi18-Oct-13 21:24 
GeneralMy vote of 5 Pin
Javier Prieto24-May-13 1:53
memberJavier Prieto24-May-13 1:53 
GeneralMy vote of 1 Pin
thefiloe17-May-13 0:42
memberthefiloe17-May-13 0:42 
GeneralMy vote of 5 Pin
Sperneder Patrick16-May-13 5:58
professionalSperneder Patrick16-May-13 5:58 
GeneralRe: My vote of 5 Pin
yani papi16-May-13 17:03
memberyani papi16-May-13 17:03 
GeneralRe: My vote of 5 Pin
jim lahey16-May-13 23:16
memberjim lahey16-May-13 23:16 
QuestionCorrected to "Class Library" Pin
yani papi15-May-13 22:16
memberyani papi15-May-13 22:16 
QuestionThanks [modified] Pin
Lance Rose26-Apr-13 9:49
memberLance Rose26-Apr-13 9:49 
AnswerRe: Thanks Pin
AlexMortola29-Apr-13 4:15
memberAlexMortola29-Apr-13 4:15 
GeneralRe: Thanks Pin
yani papi15-May-13 22:17
memberyani papi15-May-13 22:17 
QuestionCompleted and working. Pin
Lance Rose15-Apr-13 11:49
memberLance Rose15-Apr-13 11:49 
AnswerRe: Completed and working. Pin
MadDevelopers21-Mar-14 3:14
memberMadDevelopers21-Mar-14 3:14 
QuestionWhat is a Windows Library? Pin
Lance Rose15-Apr-13 11:05
memberLance Rose15-Apr-13 11:05 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150428.2 | Last Updated 17 Oct 2013
Article Copyright 2013 by yani papi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid