Getting Started with WCF (Windows Communication Foundation) - Running and Debugging Quickly

Overview

This post has an easy goal – to get you up to speed quickly and teaching you the core concepts of WCF. From this post you will be well primed to dive deep into more advanced topics, such as advanced bindings, channel layers, security, transactions, and more.

The web service that we create will be capable of supporting three types of clients. The first client will simply leverage http to send and receive data. The second client may need to take advantage of security and transactions. And the third type of client wants to leverage fast machine to machine connectivity using TCP. We will test for all the clients using the WCF Test Client.

In the next post we will explore hosting this project in IIS or in your own custom application. Then we might delve into moving it into the cloud.

Objectives

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

  • Create a WCF Service Library
  • Add an interface and a service implementation
  • Add 3 endpoints to support wsHttpBinding, basicHttpBinding, netTcpBinding
  • How to configure App.config to define the service capabilities and behaviors
  • How to debug a WCF Service using the WCF Test Client

Prerequisites

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

  • Visual Studio 2010 to 2013 - (I will be using Visual Studio 2013)
  • A desire to learn the fundamentals of web service programming on the MS stack

Setup

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

  1. Begin by starting Visual Studio

Task 1 - Creating a WCF Service Library

This task is about creating the initial WCF project to which we will add functionality.

  1. Start Visual Studio and select File/New Project.

    image001

    Visual Studio 2013 RC - File New Project

  2. Profile the name, FlipCaseService. It will be used to receive arguments as strings, and then modify them. More details of the app in future slides.

    image002

    Naming the Service

  3. You will start by deleting 2 files. The reason is to learn about adding classes. You could skip this step (and the next few).

    image003

    Deleting the Default Classes

  4. Ultimately, we need to add 3 files: (1) Data Contract (2) Interface for Service (3) Service Implementation. Right mouse click on the project and choose Add/New Item.

    image004

    Adding 1 of 3 files - The Data Contract

  5. Provide a name for what will become the definitions of Data Contracts. Name it DataContracts. Not the best name but just to drive home concepts of what that file contains.

    image005

    Naming the Data Contracts

  6. Right mouse click on the project and choose Add/New Item.

    image006

    Adding 2 of 3 files - FlipCaseService

  7. Provide a name for what will become the definitions of the service definition. Name it FlipCaseService.

    image007

    Naming the WCF Service

  8. Notice the files that we have added. Our next step will be to add code to them.

    image008

    Solution Explorer

Task 2 - Defining the Data Contracts

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

  1. Note the members that make up StringData. OriginalString will be used to pass in data - a string whose case will be reversed, lowercase becoming uppercase, and uppercase becoming lowercase. The resulting string will be placed in the data member called FlippedCaseString. You will see the actual result in future section.

    image009

    DataContracts.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace FlipCaseService
{
    [DataContract]
    public class StringData
    {
        [DataMember]
        public string OriginalString;


        [DataMember]
        public string FlippedCaseString;

    }
}
  1. Note the implementtation provided with File/New Project.

    image010

    FlipCaseService.cs - default implementation

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace FlipCaseService
{

    [ServiceContract]
    public interface IFlipCaseService
    {

        [OperationContract]
        StringData FlipTheCase(StringData sd);
    }

}

Important Notes

An interface defines what must a client know about a class in order to benefit from using it

Developers often put the interfaces into a separate assembly.

This is useful because the interface can be used by any piece of code that needs to know about the interface, but not necessarily about the implementation.

It is common practice to have one class implement more than one interface.

What is great about this is that you can expose the same implemented class in different ways using different interfaces in the WCF endpoints.

In Windows Communication Foundation (WCF) applications, you define the operations by creating a class and marking it with the [ServiceContract] attribute in the interface file. For each method in the class you can mark each method with OperationAttribute.

Interface-based programming is popular among many developers

It makes code better, by increasing reusability, maintainability, and extensibility

Interfaces became popular in languages such as C++ and Smalltalk

The argument is that using distinct interfaces could make software, especially large code-bases, easier to maintain and extend

Interfaces simplify code reuse in object-oriented programming

Interfaces allow you extend the class without breaking the client

If a client does not communicate with an object through an interface, then the client can build inflexible dependencies on a class definition

Although interfaces are not ALWAYS appropriate, many believe that not using interfaces leads to impossibly difficult code improvement better over time

More dependencies are created in the client when a programmer writes code using a class's methods and properties instead of an interface.

Read more:

https://msdn.microsoft.com/en-us/library/aa260635(v=vs.60).aspx

https://en.wikipedia.org/wiki/Interface_based_programming

  1. Notice the new implementation, which will flip the case of the string passed in.

    image011

    FlipCaseService.cs - New implementation

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace FlipCaseService
{
    public class FlipCaseService : IFlipCaseService
    {
        public StringData FlipTheCase(StringData sd)
        {
            sd.FlippedCaseString = null;
            foreach (char c in sd.OriginalString)
            {
                sd.FlippedCaseString += char.IsLower(c) ?
                      c.ToString().ToUpper() : c.ToString().ToLower();
            }
            return sd;
        }
    }
}

Task 3 - Implementing Endpoints

All communication with a Windows Communication Foundation (WCF) service occurs through the endpoints of the service. Endpoints provide clients access to the functionality offered by a WCF service.

Each endpoint consists of four properties: - An address that indicates where the endpoint can be found. - A binding that specifies how a client can communicate with the endpoint. - A contract that identifies the operations available. - A set of behaviors that specify local implementation details of the endpoint.

  1. Notice the client can access the service through different endpoints. A WCF client connects to a WCF service by communicating with an Endpoint. At each endpoint is a service contract. Also, each endpoint has an address (which is a URL specifying where the endpoint can be accessed). The endpoint also specifies binding properties which define how the data will be transferred.

    image012

    Client accessing 3 endpoints

  2. The mnemonic "ABC" is useful to know. It can be used to represent Address / Binding / Contract. The Binding indicates what communication protocols are used to access the service, what type of security mechanisms are to be used. WCF supports predefined bindings for most commonly used communication protocols such as SOAP over HTTP, SOAP over TCP, and SOAP over Message Queues. Interaction between WCF endpoint and client is typically accomplished using a SOAP envelope. SOAP envelopes are defined through XML. An important note when clients connect to services though specific endpoints. When connecting to endpoints, the client not only needs to know the contract, but it also has to adhere to the binding specified by the endpoint. Thus, both client and server must be in sync about their endpoints. Notice endpoint 1 uses wsHttpBinding and endpoint 2 uses basicHttpBinding.

    image013

    ABC's of Endpoints

  3. The definition of endpoints takes place in the App.config file. You can see the ABC's directly in the endpoint definitions.

App.config
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

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <appSettings>

    <add

      key="aspnet:UseTaskFriendlySynchronizationContext"

      value="true"/>

    <!--<add key="ClientSettingsProvider.ServiceUri" value="" />-->

  </appSettings>

  <system.web>

    <compilation debug="true"/>

    <membership defaultProvider="ClientAuthenticationMembershipProvider">

      <providers>

        <add

          name="ClientAuthenticationMembershipProvider"

          type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

          serviceUri=""/>

      </providers>

    </membership>

    <roleManager

      defaultProvider="ClientRoleProvider"

      enabled="true">

      <providers>

        <add

          name="ClientRoleProvider"

          type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

          serviceUri=""

          cacheTimeout="86400"/>

      </providers>

    </roleManager>

  </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>

    <client/>

    <services>

      <service

        behaviorConfiguration="ServiceBehaviorMetaData"

        name="FlipCaseService.FlipCaseService">

        <endpoint

          address="flipcase/wsAddress"

          binding="wsHttpBinding"

          contract="FlipCaseService.IFlipCaseService"

          bindingConfiguration="wsHttp">

          <identity>

            <dns value="localhost"/>

          </identity>

        </endpoint>

        <endpoint

          address="flipcase/basic"

          binding="basicHttpBinding"

          contract="FlipCaseService.IFlipCaseService">

          <identity>

            <dns value="localhost"/>

          </identity>

        </endpoint>

        <endpoint

          address="net.tcp://localhost/FlipCaseNetTcp"

          binding="netTcpBinding"

          contract="FlipCaseService.IFlipCaseService">

          <identity>

            <dns value="localhost"/>

          </identity>

        </endpoint>

        <endpoint

          address="flipcase/mex"

          binding="mexHttpBinding"

          contract="IMetadataExchange">

        </endpoint>

        <host>

          <baseAddresses>

            <add baseAddress="https://localhost:8080/"/>

          </baseAddresses>

        </host>

      </service>

    </services>

    <bindings>

      <wsHttpBinding>

        <binding name="wsHttp">

          <security mode="None"/>

        </binding>

      </wsHttpBinding>

    </bindings>

    <behaviors>

      <serviceBehaviors>

        <behavior name="FlipCaseService.Service1Behavior">

          <serviceMetadata

            httpGetEnabled="true"

            httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

        <behavior name="ServiceBehaviorMetaData">

          <serviceMetadata

            httpGetEnabled="true"

            httpGetUrl="https://localhost:8080/flipcase/metadata"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Task 4 - Some important information about WCF

This next section addresses basic information all WCF devs should know.

  1. The next step is to call into the WCF Service. But before the WCF Service can be called into, it needs to be hosted somewhere.

    image015

    Hosting WCF

Note 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.

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.

  1. Every process has at least one application domain, and each application domain can host zero or more WCF ServiceHost instances. WCF requires at least an application domain hosted inside a Windows process.

    image016

    Processes, Application Domains, ServiceHosts

Task 5 - Running and Debugging Your Code

  1. Hit F5 or choose from the Debug menu.

    image017

    Starting the debugging process

  2. After running the WCF Service Library, the WCF Test Client will appear. When starting debugging (F5), it will host the service in the WCF Service Host by default. And the WCF Test Client will automatically start for you to test the service. The WCF Test Client is a debugging tool to test WCF service. It is very useful to help developing WCF service. In the next step, we will be able to to debug our running service. You can see that it is configured in your project automatically. See Project Properties -> Debug -> Command line arguments.

    image018

    The WCF Test Client

Task 6 - Verifying everything works

  1. Notice the 4 steps. On the left pane, you can see the 3 FlipTheCase methods, each representing differnt ABC's, except for the contract, which is shared among all 3 endpoints. Notice in step 2 Bruno in the Original String. In step 3 I hit Invoke, which triggers the code in the WCF service to execute, flipping the case. Notice in step 4 that FlippedCaseString is now flipped (bRUNO) and represents the final result.

    image

    The WCF Test Client

Note:

There is a request and a response object.

The client will be able to read "bRUNO" in the FlippedCaseString attribute.

Summary

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

  • Create a WCF Service Library
  • How to use DataContracts to exchange data between client and WCF Service
  • Add an interface and a service implementation
  • Add 3 endpoints to support wsHttpBinding, basicHttpBinding, netTcpBinding
  • How to configure App.config to define the service capabilities and behaviors
  • How to debug a WCF Service using the WCF Test Client
  • Further reading at Aaron Skonnard's article (https://msdn.microsoft.com/en-us/magazine/cc163647.aspx)