WCF Service Hosting - How to Host a WCF Service from inside a Windows Presentation Foundation Application

 

WCF Service Hosting - How to Host a WCF Service from inside a Windows Presentation Foundation Application

Rate This
  • Comments 7

Overview

In this module we learn about client applications connecting to WCF Services. We will also learn how to host WCF applications from inside another application that acts as a host for the WCF Service. In this post we will use a Windows Presentation Foundation style application to host our WCF Service.

A WCF service can be hosted in 3 places

(1) Self-hosting in any managed .NET application (2) Hosting in a Windows service (3) Hosting in different versions of IIS.

Objectives

In this hands-on lab, you will learn how to:

  • Host a WCF Service inside of a WPF Application
  •     
  • Programatically make a WCF Service Operational
  •     
  • Programatically add Endpoints to a ServiceHost object
  •     
  • Connect to a running WCF Service from a Console Service Client Application
  •     

Prerequisites

The following is required to complete this hands-on lab:

Setup

In order to execute the exercises in this hands-on lab you need to set up your environment.

  1. Start Visual Studio and open the previous project here: (http://blogs.msdn.com/b/brunoterkaly/archive/2013/10/18/getting-started-with-wcf-windows-communication-foundation-running-and-debugging-quickly.aspx)

Task 1 – Adding a Windows Presentation Foundation (WPF) style app to host our WCF Service

This post is about hosting a WCF Application.

Hosting a service in a managed application is the most flexible option because it requires the least infrastructure to deploy. However, it is also the least robust hosting option, because managed applications do not provide the advanced hosting and management features of other hosting options in WCF, such as Internet Information Services (IIS) and Windows services.

Hosting in a Windows Service This scenario is enabled by the managed Windows service hosting option that is a long-running WCF service hosted outside of Internet Information Services (IIS) in a secure environment that is not message activated. The lifetime of the service is controlled instead by the operating system. This hosting option is available in all versions of Windows. - Windows services can be managed with the Microsoft.ManagementConsole.SnapIn in Microsoft Management Console (MMC) and can be configured to start up automatically when the system boots up. This hosting option consists of registering the application domain (AppDomain) that hosts a WCF service as a managed Windows service so that the process lifetime of the service is controlled by the Service Control Manager (SCM) for Windows services.

A WCF service that runs in the IIS environment takes full advantage of IIS features, such as process recycling, idle shutdown, process health monitoring, and message-based activation. This hosting option requires that IIS be properly configured, but it does not require that any hosting code be written as part of the application. You can use IIS hosting only with an HTTP transport.

Task 2 – Starting from the previous code base

The screen below is where we left off from the last post. You can download the code here: (http://sdrv.ms/1aOGgVQ).

  1. Let’s begin where we left off from the last post. As you can see in the red box we have a client front-end and a WCF service backend. The client is a console application and the FlipCaseService is a WCF Service Library application.

    Image001

    Starting with the default project

  2. We will now add a third project. It will act as the host application for the WCF service. Right mouse click on the solution and choose add new project.

    Image002

    Adding a WPF project

  3. From the install templates choose Windows, WPF Application. Then provide a name below (WCFHostApplication) .

    Image003

    Adding a WPF Project

  4. We will need to set two references from the WCF host appliHimation. The first reference is to the WCF service we created earlier. The second reference is to the system.servicemodel assembly, which provides us the basic functionality needed to leverage the WCF framework.

    Image004

    Add a new Reference

  5. Selecting appropriate assembly below.

    Image005

    Selecting System.ServiceModel

  6. Add a second reference.

    Image006

    Add a new Reference

  7. The second reference is the Visual Studio project for the previously written WCF service.

    Image007

    Setting a Project Reference

  8. The screen below validates that our references are correctly set.

    Image008

    Verifying our References

Task 3 – Building the user interface for our WCF Client

  1. Now we are going to edit our main screen for our WPF Hosting Application. From server Explorer double click on MainWindow.xaml. The designer should appear. Bring the tool box into view and drag a couple of buttons over to MainWindow.xaml.

    Image009

    Dragging some button controls

  2. You can edit the XAML directly (lowest red box) or you can use the Visual Studio tooling (the properties window on the right). Or you can do a combination. Notice set two properties (Content and Name).

    Image010

    Naming the buttons and changing their caption

  3. There’s a few things to notice. (1) were talking about the WCF host application. (2) you could just edit the XAML come directly. (3) it’s probably easier to right-click on the button in the designer and select properties. (4) this is where we provide the name for the control. (5) this is the text visible to the user (content).

    Image011

    Five things to realize



    I appreciate that you took the time to read this post. I look forward to your comments.

    MainWindow.xaml (WPF Host Application)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <Window
      x:Class="WCFHostApplication.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="MainWindow"
      Height="350"
      Width="525">
      <Grid>
        <Button
          x:Name="cmdStartService"
          Content="Start FlipCaseService"
          HorizontalAlignment="Left"
          Margin="174,63,0,0"
          VerticalAlignment="Top"
          Width="130"
          Click="cmdStartService_Click"/>
        <Button
          x:Name="cmdStopService"
          Content="Stop FlipCaseService"
          HorizontalAlignment="Left"
          Margin="174,119,0,0"
          VerticalAlignment="Top"
          Width="130"
          RenderTransformOrigin="0.103,0.859"
          Click="cmdStopClick"/>
      </Grid>
    </Window>
  4. Screen below shows in the finished two buttons both in terms of the designer and the lower window containing xaml.

    Image012

    Verifying our changes to the UI of our WPF Application

Task 4 – Adding Code to make the WCF Service Operational

  1. Let’s now turn our attention to the WCF Host application. Notice for the command button event cmdStartService_Click we have code that instantiates a new ServiceHost object. We will add Endpoints programmatically. The constructor for an endpoint is passed three arguments: (1) the contract or interface (2) the Binding (3) the URI that represents the endpoint into which the client connects. There are a few things to notice. Once is that the ServiceHost object has an Open() method. Also note we have both the using syntax as well as try/throw/catch.

    Image013

    Add some code to the WPF Application (code that makes our WCF Service Operational)


    I appreciate that you took the time to read this post. I look forward to your comments.

    MainWindow.xaml.cs (WPF Host Application)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    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;


    namespace WCFHostApplication
    {
        ///
        /// Interaction logic for MainWindow.xaml
        ///

        public partial class MainWindow : Window
        {
            ServiceHost host = null;
            public MainWindow()
            {
                InitializeComponent();
            }

            private void cmdStartService_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    using (host =
                            new ServiceHost(typeof(FlipCaseService.FlipCaseService)))
                    {
                        host.AddServiceEndpoint(typeof(FlipCaseService.IFlipCaseService),
                            new BasicHttpBinding(), "http://localhost:8080/flipcase/basic");

                        host.AddServiceEndpoint(typeof(FlipCaseService.IFlipCaseService),
                            new WSHttpBinding(), "http://localhost:8080/flipcase/wsAddress");

                        host.AddServiceEndpoint(typeof(FlipCaseService.IFlipCaseService),
                            new NetTcpBinding(), "net.tcp://localhost:8081/FlipCaseNetTcp");

                        host.Open();
                    }
                }
                catch (Exception ex)
                {
                    host.Abort();
                    MessageBox.Show("Error = " + ex.Message);
                }
            }

            private void cmdStopClick(object sender, RoutedEventArgs e)
            {
                host.Close();
            }
        }
    }
  2. The configuration code below is showing what the client wants to connect to. It is better that you don’t try to create this file by hand. You can get it generated for you in 2 ways. The first way is with Adding a Service Reference from the client application to the WCF Service. This was explained in a previous post. The second way is with the svcutil.exe utility (explained previously). Note the red box on the right shows the endpoint configuration information for the client to use to connect to the WCF Service. For example, the client will connect by issuing at net.tcp://localhost:8081/FlipCaseNetTcp. The reason this is being discussed is that the WCF service in this post that we are creating must match the endpoint definition used by clients that are connecting to the WCF service.

    Image014

    Looking at the configuration file of the client (making sure it matches the WCF Service)


    I appreciate that you took the time to read this post. I look forward to your comments.

    App.config (ConsoleServiceClient)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime
          version="v4.0"
          sku=".NETFramework,Version=v4.5"/>
      </startup>
      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding_IFlipCaseService"/>
          </basicHttpBinding>
          <netTcpBinding>
            <binding name="NetTcpBinding_IFlipCaseService"/>
          </netTcpBinding>
          <wsHttpBinding>
            <binding name="WSHttpBinding_IFlipCaseService">
              <reliableSession enabled="true"/>
            </binding>
          </wsHttpBinding>
        </bindings>
        <client>
          <endpoint
            address="http://localhost:8080/flipcase/wsAddress"
            binding="wsHttpBinding"
            bindingConfiguration="WSHttpBinding_IFlipCaseService"
            contract="ConsoleServiceReference.IFlipCaseService"
            name="WSHttpBinding_IFlipCaseService">
            <identity>
              <userPrincipalName value="bterkaly@redmond.corp.microsoft.com"/>
            </identity>
          </endpoint>
          <endpoint
            address="http://localhost:8080/flipcase/basic"
            binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IFlipCaseService"
            contract="ConsoleServiceReference.IFlipCaseService"
            name="BasicHttpBinding_IFlipCaseService"/>
          <endpoint
            address="net.tcp://localhost:8081/FlipCaseNetTcp"
            binding="netTcpBinding"
            bindingConfiguration="NetTcpBinding_IFlipCaseService"
            contract="ConsoleServiceReference.IFlipCaseService"
            name="NetTcpBinding_IFlipCaseService">
            <identity>
              <userPrincipalName value="bterkaly@redmond.corp.microsoft.com"/>
            </identity>
          </endpoint>
        </client>
      </system.serviceModel>
    </configuration>
  3. Let us now start the WPF Application that is hosting the WCF Service. Right mouse click on the WCFHostApplication project as seen below.

    Image015

    Starting the WPF Application (which makes the WCF Service operational and available to clients to connect to)

Task 5 – Starting our WCF Service

  1. Note that the app is running. For the WCF Service to be operational, this command button in red must be clicked. It executes the code we just discussed.

    Image016

    Click on the WPF Application button to start the WCF Service programmatically

Task 6 – Connecting to the service from the client

  1. By now the WCF Service is running. It is waiting for clients to connect to it. So now we will turn our attention to the client. Right mouse click on the WCF client application called ConsoleServiceClient and follow the debug commands.

    Image017

    Because the WCF Service is now available, we can start the client application to connect to the WCF Service

  2. Notice that it worked. The client successful passed a parameter to the WCF Service and had that service flip the case of the string passed to it by the client.

    Image018

    Verifying success

Summary

In this post, you learned a few things:

  • In this module we learned about client applications connecting to WCF Services.
  • We illustrated how a host application can make a WCF Service operational.
  • We could have chosen the console application template, but instead we chose a Windows Presentation Foundation (WPF) application template.
  • You could extend a WPF style application much more than a console style application, providing a dashboard of an interface to enable a developer to watch what is happening with the service.
  • b-stivo@microsoft.com:   Trying to implement this solution,  but running into problems.  First, I would like the WPF app to run properly even without administrative rights.  That appears to make the HTTP endpoints a problem.   I removed those endpoints,  leaving only the TCP endpoint,  the service comes up and pretends to run.   Assuming it is running, I use the WCF test client to connect and the connection is rejected.  Argh.  The WCF contract worked when executed in debug from Visual Studio, but not when I embed it in the WPF.

  • Configuration Issue

    I've provided all the source code here. If this code won't run properly, you may have configuration challenge on your particular system. This is code that runs on my system. HTHs.

    Source Code

    http://sdrv.ms/JUcOEP

  • Using your solution as is, the console application works fine, but I believe that is because the WCF Service Host is being started automatically (it is not necessary to start WCFHostApplicaton). If I uncheck the option to "Start WCF Service HOst when debugging another project in the same solution," start the WCFhostApplication (including starting service) and then start console app, I get error "no endpoint listening at http:://localhost:8080/flipcase/basic" Is there something I am missing?

  • I am also getting the same error as Brian said.... Do we need to do any more configuration?

  • Ditto...this code does not work. The service runs stand-alone but when attempting to host within the WPF application, the host.Open() fires without exception but when attempting to connect to the service (via another console app, browser, etc.) all connections are rejected.

  • FYI, the link below is the correct way to host a WCF service within a WPF app. To re-iterate, the code in this article doe not work...quite epicly, and will cause developers to waste a lot of time trying to figure out why it doesn't work. I would consider modifying this article or taking it down.

    Working implementation:

    soumya.wordpress.com/.../wcf-simplified-part-7-hosting-a-wcf-service-using-wpf

  • Hi Everyone,

    Not sure why it doesn't work for so many of you. Just a couple of right mouse clicks "Debug / Start New Instance", first on the host, then on the client.

    (1) Run the console host (2) Run the console client I just re-ran the code again and it works.

    Here is the code:

    http://1drv.ms/1lKNqA7

     Also, make sure you are running as Administrator.

Page 1 of 1 (7 items)
Leave a Comment
  • Please add 4 and 4 and type the answer here:
  • Post