Click here to Skip to main content
15,067,335 members
Articles / WCF
Technical Blog
Posted 10 Sep 2013

Tagged as

Stats

133.3K views
25 bookmarked

Creating a Self Hosted WCF Service

Rate me:
Please Sign up or sign in to vote.
4.96/5 (22 votes)
10 Sep 2013CPOL5 min read
In this post I am going to explain how to create a simple WCF Service, with Self Hosting and consume it, there will be 4 parts of the project. A Class Library (MyMathServiceLib.dll): which will implement our business logic.

In this post I am going to explain how to create a simple WCF Service, with Self Hosting and consume it, there will be 4 parts of the project.

  1. A Class Library (MyMathServiceLib.dll): which will implement our business logic.
  2. Service Host Application (MathServiceHost.exe): Application which will host this class library as a WCF Service.
  3. A Windows Client Application (MyMathServiceClient.exe): Client Application which will use this service.
  4. A Web Client, that will use this Service.

Note

part 1 and 2 can be merged into one, if one like so, but, for the sake of portability, keep them as separate modules. let’s start with creating the Class Library.

Part 1: Creating the Class Library

Start the Visual Studio, and click File->New->Project . Select the project template ‘Class Library" click OK.

image

Now let’s analyse the project created by wizard for us, and do little house keeping, before we write any code.

  • Class1.cs (The default class, created by wizard).

Assumption

We are going to create a Service as per following assumptions.

  • Interface will named as IMyMathService (IMyMathService.cs)
  • Service will be implemented as MyMathService (MyMathService.cs)

Little house keeping. (just to keep things organized)

  • Delete Class1.cs the project workspace.
  • Add an Interface (IMyMathService) IMyMathService.cs to the project.
  • Add an Class (MyMathService) MyMathService.cs to the project.
  • Add reference of System.ServiceModel to the project.

Now, let’s define the Interface and its implementation of our old familiar class Library.

// Listing of IMyMathService.cs,

C#
using System;      
using System.Collections.Generic;       
using System.Linq;       
using System.Text;       
using System.ServiceModel;namespace MyMathServiceLib      
{       
    [ServiceContract]       
    public interface IMyMathService       
    {       
        [OperationContract]       
        double Add(double dblNum1, double dblNum2);[OperationContract]      
        double Subtract(double dblNum1, double dblNum2);[OperationContract]      
        double Multiply(double dblNum1, double dblNum2);[OperationContract]      
        double Divide(double dblNum1, double dblNum2);       
    }       
}       //  Listing of MyMathService.cs, using System;      
using System.ServiceModel;       
using System.Text;       
using System.ServiceModel;namespace MyMathServiceLib      
{       
    public class MyMathService : IMyMathService       
    {       
        public double Add(double dblNum1, double dblNum2)       
        {       
            return (dblNum1 + dblNum2);       
        }public double Subtract(double dblNum1, double dblNum2)      
        {       
            return (dblNum1 – dblNum2);       
        }public double Multiply(double dblNum1, double dblNum2)      
        {       
            return (dblNum1 * dblNum2);       
        }public double Divide(double dblNum1, double dblNum2)      
        {       
            return ((dblNum2 == 0) ? 0 : (dblNum1 / dblNum2));       
        }       
    }       
}

Part 2: Creating the Host Application

Our class library is ready, let’s write an Host application, which will expose this facility to the world as a WCF Service. lets’ Create a Console based application, for the sake of simplicity, name it MyMathServiceHost, as shown below.

image

a new Project MyMathServiceHost will be added to the workspace.

Assumption

The Host application will expose the following endpoints for the service.

  • Service will implement HTTP endpoint at Port 9001
  • Corresponding mex End Point (IMetadatExchange) for the HTTP end point.
  • Service will implement TCP endpoint at Port 9002
  • Corresponding mex End Point (IMetadatExchange) for the TCP end point.

Adding reference of the class library to the Host project

  • Add reference of the class library to the console project,as shown below.

image

  • Add reference of System.ServiceModel to the project.

Creating the Service Configuration

Add a Application configuration file (App.config) to the Host Project. define the End Points and bindings according to the assumptions made at the start of the project.

  • will expose an end point with HTTP Binding at 9001
  • will expose an end point with TCP Binding at 9002
  • will expose, required mex (one for each binding) end points

below is he listing of the app.config file.

XML
<?xml versio="1.0"?>      
<configuration><system.serviceModel>      
      <services>       
        <service name="MyMathServiceLib.MyMathService" behaviorConfiguration="myMathServiceBehave">       
          <host>       
            <baseAddresses>       
              <add baseAddress="http://localhost:9001/MyMathService"/>       
              <add baseAddress="net.tcp://localhost:9002/MyMathService"/>       
            </baseAddresses>       
          </host>       
          <endpoint address="http://localhost:9001/MyMathService" binding="basicHttpBinding" contract="MyMathServiceLib.IMyMathService"/>       
          <endpoint address="net.tcp://localhost:9002/MyMathService" binding="netTcpBinding" contract="MyMathServiceLib.IMyMathService"/>       
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>       
          <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>       
        </service>       
      </services>       
      <behaviors>       
        <serviceBehaviors>       
          <behavior name="myMathServiceBehave">       
            <serviceMetadata httpGetEnabled="true"/>       
          </behavior>       
        </serviceBehaviors>       
      </behaviors>       
    </system.serviceModel>       
</configuration>
Description
  • Application configuration files defines 2 endpoints, one for TCP and one for HTTP. and 1 mex end point for each.
  • Service behavior define, <serviceMetadata httpGetEnabled="true"/> that meta data should be available through a HTTP get request.

Write code to Host the Service.

Write the code to Host the Service in the Main function of the Open Program.cs, and let’s write the code.

C#
using System;      
using System.Collections.Generic;       
using System.Linq;       
using System.Text;       
using System.ServiceModel;       
using System.ServiceModel.Description;namespace CalcServiceHost      
{       
    class Program       
    {       
        static void Main(string[] args)       
        {       
            ServiceHost svcHost = null;       
            try       
            {       
                svcHost = new ServiceHost(typeof(MyMathServiceLib.MyMathService));        
                svcHost.Open();                         Console.WriteLine("\n\nService is Running  at following address" );       
                Console.WriteLine("\nhttp://localhost:9001/MyMathService");       
                Console.WriteLine("\nnet.tcp://localhost:9002/MyMathService");       
            }       
            catch (Exception eX)       
            {       
                svcHost = null;       
                Console.WriteLine("Service can not be started \n\nError Message [" + eX.Message + "]");       
            }if (svcHost != null)      
            {       
                Console.WriteLine("\nPress any key to close the Service");       
                Console.ReadKey();       
                svcHost.Close();       
                svcHost = null;       
            }       
        }       
    }       
}
explanation

as you can see from the above code,

  • Class Library is simply hosted inside a ServiceHost object, as all the End Points are defined in App.config file.

Part 3: Creating the Windows Client

Now when our service is self hosted and running, let us write a client Application, which can use this Service. lets’ Create a Console based application, for the sake of simplicity, name it MyMathServiceClient, as shown below.

image

newly created project will be added to the work space.

Generating proxy and config file.

Before we write the Client application, we need to generate the proxy for our Service, open a command prompt in Administrator mode. and execute the Host Application.

image

Open another command prompt, switch to the folder, where client project has been created, and generate the proxy and configuration file using the SVCUtil.exe utility. as shown below.

image

add both these files to the client project.

Calling the Service

Now write the code to use the proxy and call the service, here is the listing of the Program.cs.

C#
using System;      
using System.Collections.Generic;       
using System.Linq;       
using System.Text;namespace MyMathClient      
{       
    class Program       
    {       
        static void Main(string[] args)       
        {       
            double dblX = 2000.0;       
            double dblY = 100.0;       
            double dblResult = 0;try      
            {       
                Console.WriteLine("Using TCP Binding", dblX, dblY, dblResult);MyMathServiceClient mathClient1 = new MyMathServiceClient("NetTcpBinding_IMyMathService");dblResult = mathClient1.Add(dblX, dblY);      
                Console.WriteLine("Calling Add >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient1.Subtract(dblX, dblY);      
                Console.WriteLine("Calling Sub >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient1.Multiply(dblX, dblY);      
                Console.WriteLine("Calling Mul >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient1.Divide(dblX, dblY);      
                Console.WriteLine("Calling Sub >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);Console.WriteLine("Using Basic HTTP Binding", dblX, dblY, dblResult);MyMathServiceClient mathClient2 = new MyMathServiceClient("BasicHttpBinding_IMyMathService");dblResult = mathClient2.Add(dblX, dblY);      
                Console.WriteLine("Calling Add >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient2.Subtract(dblX, dblY);      
                Console.WriteLine("Calling Sub >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient2.Multiply(dblX, dblY);      
                Console.WriteLine("Calling Mul >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);dblResult = mathClient2.Divide(dblX, dblY);      
                Console.WriteLine("Calling Sub >>  X : {0:F2}  Y : {1:F2}  Result : {2:F2}", dblX, dblY, dblResult);       
            }       
            catch (Exception eX)       
            {       
                Console.WriteLine("There was an error while calling Service [" + eX.Message + "]");       
            }       
        }       
    }       
}

and here is the output.

image

Part 4: Creating a Web Client

Create a New Web Site, using the File –> New Web Site as shown below. name it MyMathWebClient.

image

Click OK,

Now we need to add a reference to our service to this web site, right click on the newly created web site project, and click on Add Service Reference. a dialog box will pop up.

  • Enter any (TCP/HTTP) endpoint address in the address box.
  • Name the namespace, where Service Proxy will be added to the project.

image

click OK, some changes will be made to your web.config file, and App_WebReferences folder will be added, under which a Service reference "MathServiceReference" will be added.

  • a Service reference named MyMathServiceReference will be added in Service References node of the client project.
  • some changes will be made to the web.config file,

let’s analyse the changes made to web.config. open the web.config, you will find the changes at the end of the file, see the <system.ServiceModel> section, as shown below.

XML
<system.serviceModel>             
    <bindings>             
      <basicHttpBinding>             
        <binding name="BasicHttpBinding_IMyMathService"/>             
      </basicHttpBinding>             
      <netTcpBinding>             
        <binding name="NetTcpBinding_IMyMathService"/>             
      </netTcpBinding>             
    </bindings>             
    <client>             
      <endpoint address="http://localhost:9001/MyMathService&quot; binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyMathService" contract="MathServiceReference.IMyMathService" name="BasicHttpBinding_IMyMathService"/>             
      <endpoint address="net.tcp://localhost:9002/MyMathService" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMyMathService" contract="MathServiceReference.IMyMathService" name="NetTcpBinding_IMyMathService">             
        <identity><!—this value will be different on your machine –!>                          <userPrincipalName value="PRAVEEN-WIN7\BriskTech"/>             
        </identity>             
      </endpoint>             
    </client>             
</system.serviceModel>

Open the Main page of the site (Default.aspx page), double click, that will create the Page_Load handler for the Page, lets call our service in the page load handler.

C#
protected void Page_Load(object sender, EventArgs e)              
    {               
        double dblX = 10000.0 ;               
        double dblY = 2000.0 ;               
        Response.Write ( "<p>Value 1 : " + dblX.ToString ( "F2"));               
        Response.Write ( "<br>Value 2 : " + dblY.ToString ( "F2"));try              
        {               
            Response.Write("<p>Using TCP Binding");MathServiceReference.MyMathServiceClient mathProxy1 = new MathServiceReference.MyMathServiceClient("NetTcpBinding_IMyMathService");double dblResult = mathProxy1.Add(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy1.Subtract(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy1.Multiply(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy1.Divide(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));Response.Write("<p>Using Basic HTTP Binding");MathServiceReference.MyMathServiceClient mathProxy2 = new MathServiceReference.MyMathServiceClient("BasicHttpBinding_IMyMathService");dblResult = mathProxy2.Add(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy2.Subtract(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy2.Multiply(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));dblResult = mathProxy2.Divide(dblX, dblY);              
            Response.Write("<br>Calling Add >>  X : " + dblX.ToString("F2") + "  Y : " + dblY.ToString("F2") + " Result : " + dblResult.ToString("F2"));               
        }               
        catch (Exception eX)               
        {               
            Response.Write("There was an error while calling Service <p> <b>[" + eX.Message + "] </b>");               
        }               
    }

Build and run the web site, following output will be displayed.

image

that’s all folks.

License

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

Share

About the Author

Praveen Kumar Katiyar
Architect
India India
More than 10 years of experience in designing and development of GUIs and Middleware for industrial control systems.

Comments and Discussions

 
QuestionExcellent article Pin
Sanit Sharma23-Mar-21 17:33
professionalSanit Sharma23-Mar-21 17:33 
QuestionMyMathServiceClient not recognized in Client App Pin
Julian White13-Nov-17 3:53
MemberJulian White13-Nov-17 3:53 
AnswerRe: MyMathServiceClient not recognized in Client App Pin
Member 1369987828-Feb-18 1:45
MemberMember 1369987828-Feb-18 1:45 
BugImages are not available ! Pin
Member 1275801312-Nov-17 19:37
MemberMember 1275801312-Nov-17 19:37 
QuestionExcellent Article Pin
Member 126374273-Apr-17 7:35
MemberMember 126374273-Apr-17 7:35 
AnswerRe: Excellent Article Pin
Praveen Kumar Katiyar3-Apr-17 17:22
professionalPraveen Kumar Katiyar3-Apr-17 17:22 
QuestionHow to install as service Pin
Kim Dobranski27-May-15 9:27
MemberKim Dobranski27-May-15 9:27 
AnswerRe: How to install as service Pin
Praveen Kumar Katiyar27-May-15 21:54
professionalPraveen Kumar Katiyar27-May-15 21:54 
QuestionSOAP? Pin
Sethi197822-Apr-15 2:34
MemberSethi197822-Apr-15 2:34 
QuestionHTTPS? Pin
Sethi197820-Apr-15 6:01
MemberSethi197820-Apr-15 6:01 
GeneralThanks Pin
daneram2019-Apr-15 19:02
Memberdaneram2019-Apr-15 19:02 
GeneralRe: Thanks Pin
Praveen Kumar Katiyar29-Apr-15 17:59
professionalPraveen Kumar Katiyar29-Apr-15 17:59 
GeneralGreat Article Pin
David Coorey9-Apr-15 15:29
MemberDavid Coorey9-Apr-15 15:29 
GeneralRe: Great Article Pin
Praveen Kumar Katiyar14-Apr-15 20:54
professionalPraveen Kumar Katiyar14-Apr-15 20:54 
GeneralRe: Great Article Pin
Praveen Kumar Katiyar20-Apr-15 6:48
professionalPraveen Kumar Katiyar20-Apr-15 6:48 
GeneralMy vote of 5 Pin
itsho11-Mar-15 3:15
Memberitsho11-Mar-15 3:15 
GeneralRe: My vote of 5 Pin
Praveen Kumar Katiyar12-Mar-15 1:24
professionalPraveen Kumar Katiyar12-Mar-15 1:24 
GeneralRe: My vote of 5 Pin
Praveen Kumar Katiyar20-Apr-15 6:52
professionalPraveen Kumar Katiyar20-Apr-15 6:52 
GeneralMy vote of 1 Pin
Member 1105518011-Feb-15 22:43
MemberMember 1105518011-Feb-15 22:43 
GeneralRe: My vote of 1 Pin
Praveen Kumar Katiyar12-Feb-15 3:12
professionalPraveen Kumar Katiyar12-Feb-15 3:12 
GeneralMy vote of 1 Pin
Member 1134716014-Jan-15 1:22
MemberMember 1134716014-Jan-15 1:22 
GeneralMy vote of 1 Pin
Member 1134716014-Jan-15 1:22
MemberMember 1134716014-Jan-15 1:22 
GeneralMy vote of 5 Pin
Member 1134716014-Jan-15 1:21
MemberMember 1134716014-Jan-15 1:21 
GeneralRe: My vote of 5 Pin
Praveen Kumar Katiyar12-Feb-15 3:07
professionalPraveen Kumar Katiyar12-Feb-15 3:07 
GeneralMy vote of 5 Pin
pradiprenushe2-Jan-15 4:11
professionalpradiprenushe2-Jan-15 4:11 

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.