WCF Notes

Web page by Kevin Harris of Homer IL

Please contact Kevin Harris of Homer IL concerning this web site

WCF Notes


WCF is a development platform for service-oriented applications. Prior to WCF you would choose between .NET Remoting, ASMX services, and Enterprise Services to select the appropriate method of distributing business functionality. WCF provides a single programming model which contains the capabilities of all these previous technologies. With WCF you can configure services to cross process, machine, and corporate boundaries using a number of different protocols. WCF contains the plumbing for security, transactions, and reliable messaging over many protocols. Below is a list of some of the binding supported by WCF. For a full list of binding supported by WCF, see System-Provided Bindings.

  • BasicHttpBinding - Interoperability with Web services and clients supporting the WS-BasicProfile1.1 and Basic Security Profile1.0. A binding that is suitable for communicating with WS-Basic Profile conformant Web services, for example, ASP.NET Web services (ASMX)-based services. This binding uses HTTP as the transport and text/XML as the default message encoding.

  • WSHttpBinding - Interoperability with Web services and clients that support the WS-* protocols over HTTP. A secure and interoperable binding that is suitable for non-duplex service contracts.

  • WSDualHttpBinding - Duplex HTTP communications, by which the receiver of an initial message does not reply directly to the initial sender, but may transmit any number of responses over a period of time by using HTTP in conformity with WS-* protocols. A secure and interoperable binding that is suitable for duplex service contracts or communication through SOAP intermediaries.

  • WSFederationHttpBinding - HTTP communication, in which access to the resources of a service can be controlled based on credentials issued by an explicitily-identified credential provider. A secure and interoperable binding that supports the WS-Federation protocol that enables organizations that are in a federation to efficiently authenticate and authorize users.

  • NetTcpBinding - Secure, reliable, high-performance communication between WCF software entities across a network. A secure and optimized binding suitable for cross-machine communication between WCF applications.

  • NetNamedPipeBinding - Secure, relieable, high-performance communication bewtween WCF software entities on the same machine. A secure, reliable, optimized binding that is suitable for on-machine communication between WCF applications.

Endpoints are ways the client can connect to the Web service. Every endpoint must specify the ABCs of endpoints.

  1. Address - indicates where the endpoint can be found

  2. Binding - specifies how a client can communicate with the endpoint

  3. Contract - identifies the operations available. Usually specified in an Interface.

Transport Protocols define how information travels from endpoint to endpoint. Four types of transport protocols available in WCF are:

  • HTTP - Hyptertext Transfer Protocol. Traditional request/response pattern. Main value is interoperability with non-WCF clients.

  • TCP - Transmission Control Protocol. Provides end-to-end error detection and correction. Provides reliable data delivery (handles lost and duplicate packages). If the fastes of all the bindings. Can go around routers, Network Address Translation.

  • MSMQ - Message Queuing. Allows applications to communicate in a fail-safe manner. A queue (temporary storage location) is used to hold messages which can be sent and received reliably. Enables communication across networks and between computers which many not be constantly connected. Is an technology used in occasionally connected systems.

  • Named Pipes - WCF applictions communication with each other on the same machine. Efficient because it ties into Windows operating system kernel, using a section of shared memory used for communicating.

Encodings define the format of the data. Three types of encoding in WCF are:

  1. Text - uses base64 encoding which can make messages up to 30% larger.

  2. Binary - is the fastest encoding. Unless sending very large messages, binary format is ideal (with the assumption that text isn't needed for interoperability).

  3. MTOM - Message Transmission Optimization Mechanism. Is for large amount of binary data. Is the W3C method for efficiently sending binary data to and from Web services. MTOM does not use base64 encoding for binary attachments keeping the overall size small. MTOM is based on open specifications and is largely interoperable.

Will probably use binary format most of the time, unless sending large payloads, such as movies or pictures, then use MTOM. Typically Text in WCF is XML oriented where RESTful services are JSON oriented. WCF uses Simple Object Access Protocol (SOAP) as its messaging protocol. SOAP relies on XML. SOAP can easily tunnel through firewalls and proxies without modification. WCF encodes the transmissions in a SOAP envelope which can be proportionally large compared to small payloads. Due to the verbose XML format, messages using SOAP can be large and cause slow transmission.

Another aspect which is different when comparing WCF with REST is that WCF is associated with the WS-* specifications. There are many Web service specifications in varying degrees of maturity maintained and supported by various standards bodies and entities. These specifications can complement, overlap, and compete with each other. A few of the SW-* specifications include: WS-Security, WS-RelieableMessaging, WS-Coordination, WS-AtomicTransaction, WS-Policy, WS-Discover, WS-Management, and WS-I Basic Profile. Because SOAP supports all these specifications, it is very powerful, and that is why in many cases REST can not measure up to the power of SOAP.

WCF Service Library with Console Client

Below is a WCF Service Library created in Visual Studio 2015 using the WCF Library Template, with a couple of minor modifications. Inside the same solution is a console application which calls the service.

 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
64
65
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="ReverseService.ReverseService">
        <endpoint address="Reverse/ws"
                binding = "wsHttpBinding"
                bindingConfiguration="wsHttp"
                contract="ReverseService.IReverseService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="Reverse/basic"
                binding = "basicHttpBinding"
                contract="ReverseService.IReverseService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="net.tcp://localhost/Reverse"
                binding = "netTcpBinding"
                contract="ReverseService.IReverseService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/ReverseService/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="None" />
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


App.config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
using System.Runtime.Serialization;

namespace ReverseService
{
    [DataContract]
    public class StringData
    {
        [DataMember]
        public string InString;

        [DataMember]
        public string OutString;
    }
}


StringData.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
using System.ServiceModel;

namespace ReverseService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IReverseService
    {
        [OperationContract]
        StringData ReverseTheString(StringData sd);
    }    
}


IReverseService.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
using System;

namespace ReverseService
{
    public class ReverseService : IReverseService
    {
        public StringData ReverseTheString(StringData sd)
        {
            char[] arr = sd.InString.ToCharArray();
            Array.Reverse(arr);
            sd.OutString = new string(arr);
            return sd;
        }
    }
}


ReverseService.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using ConsoleClient.ServiceReferenceWcf;
using System;

namespace ConsoleClient
{
    class Program
    {
        static void Main(string[] args)
        {
            ReverseServiceClient client = new ReverseServiceClient("BasicHttpBinding_IReverseService");
            StringData sd = new StringData();
            sd.InString = "Kevin Harris";
            sd = client.ReverseTheString(sd);
            Console.WriteLine("The reversed text is: " + sd.OutString);
            Console.ReadLine();
        }
    }
}


Program.cs

Hosting

WCF services can be hosted in these different ways:

  1. IIS - an effective way to host the service. It makes the service widely available and contains features such and health monitoring and deployment options.

  2. Windows Service - almost within the Windows operating system. Can start up automatically when system boots up. Can be controlled with the Control Panel.

  3. Most .NET Apps - a.k.a self-hosting. Requires least infrastructure but is the least robust. Using the ServiceHost class can be implemented in most .NET mananged applications (e.g. Console, WPF, ASP.NET, etc), but can not be hosted from Windows apps.

Self-hosting is convenient for testing and demonstrations, but IIS and Windows Service are typically the options used when deployed to production.These two hosting options are more robust and are more automated.

Below is a WPF application which implements the Service Host class for hosting the WCF service. The project references the System.ServiceModel and the WCF (WcfServiceLibrary1, created above) assemblies.

 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
using System;
using System.Windows;
using System.ServiceModel;

namespace WpfHost
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ServiceHost host = null;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (host = new ServiceHost(typeof(ReverseService.ReverseService)))
                {
                    host.Open();
                    MessageBox.Show("Service is ready ...");
                }
            }
            catch (Exception ex)
            {
                host.Abort();
                MessageBox.Show("Error = " + ex.Message);
            }
        }
    }
}


MainWindow.xaml.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<Window x:Class="WpfHost.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfHost"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button x:Name="button" Content="Host WCF" FontSize="20" Click="Button_Click" HorizontalAlignment="Left" Margin="111,107,0,0" VerticalAlignment="Top" Width="300" Height="80"/>

    </Grid>
</Window>


MainWindow.xaml

.WpfHost


WpfHost Project

.ReverseService WCF Project


ReverseService WCF Project

.ConsoleClient Console Client Project


ConsoleClient Console Client Project

Tags: