Click here to Skip to main content
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

 
SuggestionResolve SchoolServiceHost Issue PinmemberDina Hess6-Nov-14 5:58 
QuestionGreat article. Here are some additional tips PinmemberKiethBiasillo5-Sep-14 20:37 
QuestionThanks Pinmembermy_magic25-Aug-14 1:11 
GeneralThank you PinmemberMember 10367186 (Pratheek)29-Jun-14 20:28 
QuestionError on Program.cs in SchoolServiceHost ... PinmemberMember 104575434-Jun-14 7:48 
AnswerRe: Error on Program.cs in SchoolServiceHost ... PinmemberMember 1091885529-Jul-14 5:26 
QuestionGetting Error - Please Guide PinmemberMadDevelopers21-Mar-14 3:10 
AnswerRe: Getting Error - Please Guide Pinmembersarath rachuri2-Nov-14 23:54 
QuestionWSDL PinmembercarmiFr-117-Mar-14 11:50 
QuestionGuys Help Me I got Error PinmemberDharmaprabhu.M7-Mar-14 3:05 
QuestionHelp me : I got some error PinmemberDharmaprabhu.M7-Mar-14 3:01 
AnswerRe: Help me : I got some error PinmemberDharmaprabhu.M20-Mar-14 3:48 
Question.Net Framework PinmemberMember 106464235-Mar-14 12:21 
AnswerRe: .Net Framework PinmembercarmiFr-117-Mar-14 11:53 
GeneralRe: .Net Framework PinmemberMember 104575434-Jun-14 7:52 
QuestionError when running "SchoolServiceHost.exe" Pinmembernemoze4-Jan-14 14:09 
GeneralMy vote of 5 Pinmembermvrene6-Nov-13 15:12 
QuestionNice job PinmemberMember 963308418-Oct-13 13:09 
AnswerRe: Nice job Pinmemberyani papi18-Oct-13 21:24 
GeneralMy vote of 5 PinmemberJavier Prieto24-May-13 1:53 
GeneralMy vote of 1 Pinmemberthefiloe17-May-13 0:42 
GeneralMy vote of 5 PinprofessionalSperneder Patrick16-May-13 5:58 
GeneralRe: My vote of 5 Pinmemberyani papi16-May-13 17:03 
GeneralRe: My vote of 5 Pinmemberjim lahey16-May-13 23:16 
QuestionCorrected to "Class Library" Pinmemberyani papi15-May-13 22:16 

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
Web01 | 2.8.141223.1 | Last Updated 17 Oct 2013
Article Copyright 2013 by yani papi
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid