How to: Host and Run a Basic Windows Communication Foundation Service

This is the third of six tasks required to create a Windows Communication Foundation (WCF) application. For an overview of all six of the tasks, see the Getting Started Tutorial topic.

This topic describes how to host a Windows Communication Foundation (WCF) service in a console application. This procedure consists of the following steps:

  • Create a console application project to host the service.

  • Create a service host for the service.

  • Enable metadata exchange.

  • Open the service host.

A complete listing of the code written in this task is provided in the example following the procedure.

To create a new console application to host the service

  1. Create a new Console Application project by right-clicking on the Getting Started solution, selecting, Add, New Project. In the Add New Project dialog on the left hand side of the dialog select Windows under C# or VB. In the center section of the dialog select Console Application. Name the project GettingStartedHost.

  2. Set the target framework of the GettingStartedHost project to .NET Framework 4.5 by right clicking on GettingStartedHost in the Solution Explorer and selecting Properties. In the dropdown box labeled Target Framework select .NET Framework 4.5. Setting the target framework for a VB project is a little different, in the GettingStartedHost project properties dialog, click the Compile tab on the left-hand side of the screen, and then click the Advanced Compile Options button at the lower left-hand corner of the dialog. Then select .NET Framework 4.5 in the dropdown box labeled Target Framework.

    Setting the target framework will cause Visual Studio 2012 to reload the solution, press OK when prompted.

  3. Add a reference to the GettingStartedLib project to the GettingStartedHost project by right clicking on the References folder under the GettingStartedHost project in the solution explorer and select Add Reference. In the Add Reference dialog, select Solution on the left-hand side of the dialog and select GettingStartedLib in the center section of the dialog and click Add. This makes the types defined in GettingStartedLib available to the GettingStartedHost project.

  4. Add a reference to System.ServiceModel to the GettingStartedHost project by right-clicking the Reference folder under the GettingStartedHost project in Solution Explorer and select Add Reference. In the Add Reference dialog select Framework on the left-hand side of the dialog. In the Search Assemblies textbox, type in System.ServiceModel. In the center section of the dialog select System.ServiceModel, click the Add button, and click the Close button. Save the solution by clicking the Save All button below the main menu.

To host the service

  • Open the Program.cs or Module.vb file and enter the following code:

    // program.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using GettingStartedLib;
    using System.ServiceModel.Description; 
    
    namespace GettingStartedHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Step 1 Create a URI to serve as the base address.
                Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
    
                // Step 2 Create a ServiceHost instance
                ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
    
                try
                {
                    // Step 3 Add a service endpoint.
                    selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");
    
                    // Step 4 Enable metadata exchange.
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    selfHost.Description.Behaviors.Add(smb);
    
                    // Step 5 Start the service.
                    selfHost.Open();
                    Console.WriteLine("The service is ready.");
                    Console.WriteLine("Press <ENTER> to terminate service.");
                    Console.WriteLine();
                    Console.ReadLine();
    
                    // Close the ServiceHostBase to shutdown the service.
                    selfHost.Close();
                }
                catch (CommunicationException ce)
                {
                    Console.WriteLine("An exception occurred: {0}", ce.Message);
                    selfHost.Abort();
                }
            }
        }
    }
    
    
    ‘Module1.vb
    Imports System
    Imports System.ServiceModel
    Imports System.ServiceModel.Description
    Imports GettingStartedLibVB.GettingStartedLib
    
    Module Service
    
        Class Program
            Shared Sub Main()
                ' Step 1 Create a URI to serve as the base address
                Dim baseAddress As New Uri("http://localhost:8000/ServiceModelSamples/Service")
    
                ' Step 2 Create a ServiceHost instance
                Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
                Try
    
                    ' Step 3 Add a service endpoint
                    ' Add a service endpoint
                    selfHost.AddServiceEndpoint( _
                        GetType(ICalculator), _
                        New WSHttpBinding(), _
                        "CalculatorService")
    
                    ' Step 4 Enable metadata exchange.
                    Dim smb As New ServiceMetadataBehavior()
                    smb.HttpGetEnabled = True
                    selfHost.Description.Behaviors.Add(smb)
    
                    ' Step 5 Start the service
                    selfHost.Open()
                    Console.WriteLine("The service is ready.")
                    Console.WriteLine("Press <ENTER> to terminate service.")
                    Console.WriteLine()
                    Console.ReadLine()
    
                    ' Close the ServiceHostBase to shutdown the service.
                    selfHost.Close()
                Catch ce As CommunicationException
                    Console.WriteLine("An exception occurred: {0}", ce.Message)
                    selfHost.Abort()
                End Try
            End Sub
        End Class
    
    End Module
    
    
    1. Step 1 - Creates an instance of the Uri class to hold the base address of the service. Services are identified by a URL which contains a base address and an optional URI. The base address is formatted as follows:[transport]://[machine-name or domain][:optional port #]/[optional URI segment]The base address for the calculator service uses the HTTP transport, localhost, port 8000, and the URI segment “GettingStarted”

    2. Step 2 – Creates an instance of the ServicHost class to host the service. The constructor takes two parameters, the type of the class that implements the service contract, and the base address of the service.

    3. Step 3 – Creates a ServiceEndpoint instance. A service endpoint is composed of an address, a binding, and a service contract. The ServiceEndpoint constructor therefore takes the service contract interface type, a binding, and an address. The service contract is ICalculator, which you defined and implement in the service type. The binding used in this sample is WSHttpBinding which is a built-in binding that is used for connecting to endpoints that conform to the WS-* specifications. For more information about WCF bindings, see Windows Communication Foundation Bindings Overview. The address is appended to the base address to identify the endpoint. The address specified in this code is “Calculator” so the fully qualified address for the endpoint is “http://localhost:8000/GettingStartedService/Calculator”

      Important noteImportant

      Adding a service endpoint is optional when using .NET Framework 4 or later. In these versions, if no endpoints are added in code or configuration, WCF adds one default endpoint for each combination of base address and contract implemented by the service. For more information about default endpoints see Specifying an Endpoint Address. For more information about default endpoints, bindings, and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.

    4. Step 4 – Enable metadata exchange. Clients will use metadata exchange to generate proxies that will be used to call the service operations. To enable metadata exchange create a ServiceMetadataBehavior instance, set it’s HttpGetEnabled property to true, and add the behavior to the Behaviors collection of the ServiceHost instance.

    5. Step 5 – Open the ServiceHost to listen for incoming messages. Notice the code waits for the user to hit enter. If you do not do this, the app will close immediately and the service will shut down.Also notice a try/catch block used. After the ServiceHost has been instantiated, all other code is placed in a try/catch block. For more information about safely catching exceptions thrown by ServiceHost, see Avoiding Problems with the Using Statement

To verify the service is working

  1. Run the GettingStartedHost console application from inside Visual Studio 2012. When running on Windows Vista and later operating systems, the service must be run with administrator privileges. Because Visual Studio was run with Administrator privileges, GettingStartedHost is also run with Administrator privileges. You can also start a new command prompt running it with Administrator privileges and run service.exe within it.

  2. Open Internet Explorer and browse to the service's debug page at http://localhost:8000/GettingStarted/CalculatorService.

The following example includes the service contract and implementation from previous steps in the tutorial and hosts the service in a console application.

To compile this with a command-line compiler, compile IService1.cs and Service2.cs into a class library referencing System.ServiceModel.dll. And compile Program.cs to a console application.

// IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace GettingStartedLib
{
        [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
        public interface ICalculator
        {
            [OperationContract]
            double Add(double n1, double n2);
            [OperationContract]
            double Subtract(double n1, double n2);
            [OperationContract]
            double Multiply(double n1, double n2);
            [OperationContract]
            double Divide(double n1, double n2);
        }
}

// Service1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace GettingStartedLib
{
    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            double result = n1 + n2;
            Console.WriteLine("Received Add({0},{1})", n1, n2);
            // Code added to write output to the console window.
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Subtract(double n1, double n2)
        {
            double result = n1 - n2;
            Console.WriteLine("Received Subtract({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Multiply(double n1, double n2)
        {
            double result = n1 * n2;
            Console.WriteLine("Received Multiply({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }

        public double Divide(double n1, double n2)
        {
            double result = n1 / n2;
            Console.WriteLine("Received Divide({0},{1})", n1, n2);
            Console.WriteLine("Return: {0}", result);
            return result;
        }
    }
}

//Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using GettingStartedLib;
using System.ServiceModel.Description; 

namespace GettingStartedHost
{
    class Program
    {
        static void Main(string[] args)
        {
            // Step 1 of the address configuration procedure: Create a URI to serve as the base address.
            Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

            // Step 2 of the hosting procedure: Create ServiceHost
            ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            try
            {
                // Step 3 of the hosting procedure: Add a service endpoint.
                selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");

                // Step 4 of the hosting procedure: Enable metadata exchange.
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                selfHost.Description.Behaviors.Add(smb);

                // Step 5 of the hosting procedure: Start (and then stop) the service.
                selfHost.Open();
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                selfHost.Close();
            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("An exception occurred: {0}", ce.Message);
                selfHost.Abort();
            }
        }
    }
}

‘IService1.vb
Imports System
Imports System.ServiceModel

Namespace GettingStartedLib

    <ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
    Public Interface ICalculator

        <OperationContract()> _
        Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
        <OperationContract()> _
        Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
    End Interface
End Namespace

‘Service1.vb
Imports System
Imports System.ServiceModel


Namespace GettingStartedLib

    Public Class CalculatorService
        Implements ICalculator

        Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
            Dim result As Double = n1 + n2
            ' Code added to write output to the console window.
            Console.WriteLine("Received Add({0},{1})", n1, n2)
            Console.WriteLine("Return: {0}", result)
            Return result
        End Function

        Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
            Dim result As Double = n1 - n2
            Console.WriteLine("Received Subtract({0},{1})", n1, n2)
            Console.WriteLine("Return: {0}", result)
            Return result

        End Function

        Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
            Dim result As Double = n1 * n2
            Console.WriteLine("Received Multiply({0},{1})", n1, n2)
            Console.WriteLine("Return: {0}", result)
            Return result

        End Function


        Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
            Dim result As Double = n1 / n2
            Console.WriteLine("Received Divide({0},{1})", n1, n2)
            Console.WriteLine("Return: {0}", result)
            Return result

        End Function
    End Class
End Namespace

‘Module1.vb
Imports System
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports GettingStartedLibVB.GettingStartedLib

Module Service

    Class Program
        Shared Sub Main()
            ' Step 1 of the address configuration procedure: Create a URI to serve as the base address.
            Dim baseAddress As New Uri("http://localhost:8000/ServiceModelSamples/Service")

            ' Step 2 of the hosting procedure: Create ServiceHost
            Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
            Try

                ' Step 3 of the hosting procedure: Add a service endpoint.
                ' Add a service endpoint
                selfHost.AddServiceEndpoint( _
                    GetType(ICalculator), _
                    New WSHttpBinding(), _
                    "CalculatorService")

                ' Step 4 of the hosting procedure: Enable metadata exchange.
                ' Enable metadata exchange
                Dim smb As New ServiceMetadataBehavior()
                smb.HttpGetEnabled = True
                selfHost.Description.Behaviors.Add(smb)

                ' Step 5 of the hosting procedure: Start (and then stop) the service.
                selfHost.Open()
                Console.WriteLine("The service is ready.")
                Console.WriteLine("Press <ENTER> to terminate service.")
                Console.WriteLine()
                Console.ReadLine()

                ' Close the ServiceHostBase to shutdown the service.
                selfHost.Close()
            Catch ce As CommunicationException
                Console.WriteLine("An exception occurred: {0}", ce.Message)
                selfHost.Abort()
            End Try
        End Sub
    End Class

End Module

NoteNote

Services such as this one require permission to register HTTP addresses on the machine for listening. Administrator accounts have this permission, but non-administrator accounts must be granted permission for HTTP namespaces. For more information about how to configure namespace reservations, see Configuring HTTP and HTTPS. When running under Visual Studio, the service.exe must be run with administrator privileges.

Now the service is running. Proceed to How to: Create a Windows Communication Foundation Client. For troubleshooting information, see Troubleshooting the Getting Started Tutorial.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft