Content:
1. Simplest web service
2. Deployment
3. Web server
4. Terminology
5. Binding Types
6. Deployment options
7. Self host
8. Consuming the web service - client
9. Create client without service reference and app.config
10. Debugging WCF service from Visual Studio
11. web.config|web.debug.config|web.release.config
12. Data format
   - Simple data types
   - Composite data types
13. WCF as REST
14. Enable exceptions in output
15. Large messages
16. Extensibility-versioning
17. Performance
18. Testing
   - Dependency injection (with Unity)
19. Security
   - Turn off authentication (in config)
   - Using SSL
   - WCF: install certificate in local machine storage
20. WCF: Assign certificate to client in code
21. WCF: Add http header to request


WCF stands for Windows Communication Foundation and you read more about it on MSDN

Windows Communication Foundation (MSDN)
- Learning WCF (MSDN)
Getting Started Tutorial (MSDN)
How to articles (MSDN - patterns & practices)

Computer setup for WCF (with IIS,Firewall) (MSDN)
- Configuring HTTP and HTTPS for WCF (MSDN)
- Server Certificate Installation Instructions (MSDN)


1. Simplest web service

In order to create WCF web service you need an .svc file that may look like the file below. This example demonstrates a simple service that is able to take an argument and return data. The web service needs to have an interface that defines the functionality the web service will provide and it needs to be attributed with [ServiceContract]. Each web service call needs to be attributed with [OperationContract]. The implementation consist of a class that implements the Interface.

C#
<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceSimpleNs.WcfServiceSimple" %>

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceSimpleNs
{
    [ServiceContract]
    public interface IWcfServiceSimple
    {
        [OperationContract]
        string GetData(int value);
    }
    
    public class WcfServiceSimple : IWcfServiceSimple
    {
        public string GetData(int value)
        {
            return string.Format("Simplest: Argument passed: {0}", value);
        }
    }
}

2. Deployment

Available options

3. Web server

In order to deploy a WCF web service to a web server you need Microsoft Internet Informational Services (IIS) installed. By default, root of your web server is located at c:\intepub\wwrroot
Create a folder, e.g. WcfSimple
Save the content and the web service code above to WcfSimple.svc and save it under WcfSimple folder.

You need to right click on the folder and select "Convert to application"
Make sure that you select the AppPool with Integrated Pipeline mode (When you use classic you wil get 500.21 Error)

Open web browser and type: http://localhost/WcfSimple/WcfSimple.svc
The browser will show you message: Metadata publishing for this service is currently disabled.
WCF web service requires configuration file. A minimum configuration file you can find below.
Note: if you do not have any service listed in your config at all, when debugging from Visual Studio with IIS Express or when hosting in IIS, the hosting server will detect if a service is available and expose it with basicHttpBinding

XML
<configuration>
    <system.serviceModel>
 
        <services>
            <!-- Note: the service name must match the configuration name for the service implementation. -->
            <service 
                name="WcfServiceSimpleNs.WcfServiceSimple"  
                behaviorConfiguration="MyServiceTypeBehaviors" >
                
                <endpoint 
                   address="" 
                   binding="wsHttpBinding" 
                   contract="WcfServiceSimpleNs.IWcfServiceSimple" />

            </service>
        </services>
 
        <behaviors>
            <serviceBehaviors>
                <behavior name="MyServiceTypeBehaviors" >

                    <serviceMetadata httpGetEnabled="true" />

                </behavior>
            </serviceBehaviors>
        </behaviors>
 
    </system.serviceModel>
</configuration>
Now the service appears in browser. In order to see WSDL, you need to type http://localhost/WcfSimple/WcfSimple.svc?wsdl
if you want to disable wsdl, set

XML
<serviceMetadata httpGetEnabled="false" />

Be aware that the when the service is hosted by IIS then the service reads its System.ServiceModel configuration from web.config, not from MyService.dll.config, that gets created by Visual Studio. MyService.dll.config would be used if the service is selfhosted.

4. Terminology

You may have heard or read about so called ABC. Now you can see it in the web.config
Address - specify location of the service. Client will need to set this to URL of the service.
Binding - defines how client communicates with the service (SOAP, REST, ..)
Contract - defines data transferred (IWcfServiceSimple interface)


5. Binding Types

basicHttpBinding - SOAP 1.1 (weak security; great on intercompatilibility
wsHttpBinding - SOAP 1.2 (security, reliable messiging, sessionfull connections; heavier
webHttpBinding - REST (does not require a SOAP client to access the messages, XML or JSON retuned based on URL)
netTcpBinding - optimized and faster than wsHttpBinding, secure, intended for WCF-to-WCF communication
All bnding types on MSDN

6. Deployment options

1. one embeded file (described above)
2. .svc and .svc.cs file. You can split the .svc file above to WcfSimple.svc

C#
<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceSimpleNs.WcfServiceSimple" %>
and \App_Code\WcfServiceSimple.svc.cs files.

C#
using System;
...
namespace WcfServiceSimpleNs
{
    public interface IWcfServiceSimple  {  ...  }
    
    public class WcfServiceSimple : IWcfServiceSimple  { ... }
}
3. You can compile .svc.cs to a .net dll binary (from Visual Studio or command line) and copy it to \bin folder of the web service.

You may need to run c:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\ServiceModelReg.exe -i to install WCF components.

7. Self host

If you do not want to deploy to a web server, you can compile an .exe that will work as host.

1. Create console application
2. add reference to System.ServiceModel

C#
  // Must be executed with VS running As Administrator
  static void Main(string[] args)
  {
      Uri baseSvcAddress = new Uri("http://localhost:9000/MyServiceHost");

      // Create the host
      using (ServiceHost host = new ServiceHost(typeof(WcfServiceSimple), baseSvcAddress))
      {
          // Enable metadata
          ServiceMetadataBehavior svcMetadataBehavior = new ServiceMetadataBehavior();
          svcMetadataBehavior.HttpGetEnabled = true;
          svcMetadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
          host.Description.Behaviors.Add(svcMetadataBehavior);

          // base service address will be used.
          host.Open();

          Console.WriteLine("The service is running at {0}", baseSvcAddress);
          Console.WriteLine("Press 'Enter' to stop the service.");
          Console.ReadLine();

          // Close the host.
          host.Close();
      }
  }

8. Consuming the web service - client

Consuming WCF service:

When developing in Visual Studio In order to be able to create a client with a proxy, you do not need to deploy the service
1. In the same solution as the service project is located, Create a New project (e.g. a Console app)
2. Right click on References and select "Add Service Reference .."
3. Click "Discover/Service in Solution"
When consuming a public service
3. Enter the url of the running wcf service and click Go

4. Visual Studio will generate a Service References folder with a subfolder for your wcf service with about 9 files. Reference.cs file that represents the proxy to the service is created under the subfolder.

C#
// create client using defined configuration from 
using (var client = new WcfServiceSimpleClient("BasicHttpBinding_IWcfServiceSimple"))
{
	// call a service method with 1 argument
	string result = client.GetData(2);
}

9. Create client without service reference and app.config

It is possible to create a client and call his methods without specifying parameters in config file and creating webservice reference. The service interface is needed.

C#
// create channel
var myBinding = new WebHttpBinding();
var myEndpoint = new EndpointAddress("http://myurl.net");
var channelFactory = new ChannelFactory<IMyInterface>(myBinding, myEndpoint);
channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());
IComplianceFacade client = null;

client = channelFactory.CreateChannel();

// make the call
client.MyMethod();

// close channel
channelFactory.Close();

10. Debugging WCF service from Visual Studio

- In Visual Studio, in Solution Explorer, click on the .svc file.
- Press F5, WCF Test Client will be opened (VS 2013).
- Put a break point into the method that you want to debug
- Select the method in the left panel and click Invoke

Note 1: the service output must be in bin\ folder
Note 2: the <UseIIS> flag in .csproj file must be set to "true" in order the test client starts
Note 3: if you have your own client in the same solution, you can either start both the service and your own client by right clicking on the solution and selecting "Set StartUp Projects..." or just select the client as startup project and VS will start IIS with Service automatically
Note 4: you need to have an endpoint that exposes SOAP based binding (BasicHttpBinding or wsHttpBinding) to see the service in WCF Test Client
Note 5: Visaul Studio starts IIS Express. Make sure that it gets closed before you start the updated service (right on the IIS Express icon in the Task bar, click Exit).

11. web.config|web.debug.config|web.release.config

The same section in web.config gets replaced with content of web.release.config or web.release.config (with help of xlst transformation) when the service gets deployed from Visual Studio (2013) using Publish action.

This will not happen during build (F5 in Visual Studio).

Usage: It is useful e.g. for replacing connection string (from local dev DB used during development when starting the service from Visual Studio) to production DB when deploying to production.

web.config

XML
<connectionStrings>
  <add name="MyDB" 
    connectionString="Data Source=.;Initial Catalog=DevelopmentDB;Integrated Security=True" />
</connectionStrings>
</code>
web.release.config

XML
<connectionStrings>
  <add name="MyDB" 
	connectionString="Data Source=ProductionSQLServer;Initial Catalog=ProductionDB;Integrated Security=True" 
	xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
If the the same action is required to happen during build, there are multiple ways how to run the transformation described here .

12. Data format

Now we can take a look what data is being transmited. WCF uses by default SOAP format.

Simple data types

For the method below using simple data types

C#
public string MyMethod(int myIntValue, string myStringValue)
{
	return string.Format("Arguments passed: {0} {1}", myIntValue, myStringValue);
}
here is data send as request:

XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IWcfServiceSimple/MyMethod</Action>
  </s:Header>
  <s:Body>
    <MyMethod xmlns="http://tempuri.org/">
      <myIntValue>2</myIntValue>
      <myStringValue>abc</myStringValue>
    </MyMethod>
  </s:Body>
</s:Envelope>
and as response:

XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <MyMethodResponse xmlns="http://tempuri.org/">
      <MyMethodResult>Arguments passed: 2 abc</MyMethodResult>
    </MyMethodResponse>
  </s:Body>
</s:Envelope>

Composite data types

For the method below using composite data types

C#
[DataContract]
public class MyCompositeType
{
	bool boolValue = true;
	string stringValue = "Hello ";

	[DataMember]
	public bool BoolValue
	{
		get { return boolValue; }
		set { boolValue = value; }
	}

	[DataMember]
	public string StringValue
	{
		get { return stringValue; }
		set { stringValue = value; }
	}
}
	
public MyCompositeType GetDataUsingDataContract(MyCompositeType composite)
{
	return composite;
}
here is data send as request:

XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IWcfServiceSimple/GetDataUsingDataContract</Action>
  </s:Header>
  <s:Body>
    <GetDataUsingDataContract xmlns="http://tempuri.org/">
      <composite xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfServiceSimple" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <d4p1:BoolValue>false</d4p1:BoolValue>
        <d4p1:StringValue>abc</d4p1:StringValue>
      </composite>
    </GetDataUsingDataContract>
  </s:Body>
</s:Envelope>
and as response:

XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
      <GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfServiceSimple" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:BoolValue>false</a:BoolValue>
        <a:StringValue>abc</a:StringValue>
      </GetDataUsingDataContractResult>
    </GetDataUsingDataContractResponse>
  </s:Body>
</s:Envelope>

13. WCF as REST

Large article explaining the concept and many details is available on MSDN

In order to create a WCF REST service that would allow access from web browser like mydomain.net/myservice/myresource using HTTP verbs like GET, POST, PUT, DELETE it is necessary to

1. Attribute the web method with [WebGet] or [WebInvoke] (POST, PUT or DELETE)

C#
[OperationContract]
[WebGet(UriTemplate = "MyMethodRest/{myStringValue}/{myStringValue2}")]
string MyMethodRest(string myStringValue, string myStringValue2);

2. Define an end point with that is configured with and uses webHttpBinding

XML
<services>
	<service name="WcfServiceSimple.Service1">
		<endpoint 
			 behaviorConfiguration="webBehavior" 
			 binding="webHttpBinding" 
			 contract="WcfServiceSimple.IWcfServiceSimple" />
	</service>
</services>

<behaviors>
	<endpointBehaviors>
		<behavior name="webBehavior"
		  <webHttp />
		</behavior>
	</endpointBehaviors>
</behaviors>
Such a method can be called from browser as:

XML
http://localhost:25719/WcfServiceSimple.svc/MyMethodRest?myStringValue=abc&myStringValue2=def
http://localhost:25719/WcfServiceSimple.svc/MyMethodRest/abc/def
Result in Browser

XML
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Arguments passed: abc def</string>
!!!If UriTemplate is used then all argumentw that are used in the template must be type of string.

If JSON is required, it can defined as below

C#
[WebGet(ResponseFormat = WebMessageFormat.Json)]  // or WebMessageFormat.Xml

14. Enable exceptions in output

There are 2 ways how it is possible to enable exceptions 1. In code

C#
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WcfServiceSimple : IWcfServiceSimple
2. config file

XML 
<system.serviceModel>
    <services>
      <service name="ServiceNamespace.ServiceClassName"  behaviorConfiguration ="DebugEnabled">
      </service>
    </services>
    <behaviors>
      <serviceBehaviors >
        <behavior name="DebugEnabled">
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel> 

15. Large messages

When you need to create service that will transport large amount of data, you need to change default service configuration

XML
<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="largeMessageBinding"
        receiveTimeout="00:10:00" 
        sendTimeout="00:10:00"
        maxReceivedMessageSize="1000485760"
       >
        <readerQuotas maxArrayLength="1000485760"/>
      </binding>
    </netTcpBinding>
  </bindings>

  <services>
    <service 
      name="largeMessageService"
      <endpoint 
         binding="netTcpBinding" 
         bindingConfiguration="largeMessageBinding" 
         ... />
   </service>
  <services>
</system.serviceModel>


16. Extensibility-versioning

If you add a new field as last field to a composite type on the service side and do not update the composite type on the client side, you can still call the service and the fields of the composite type defined in the proxy used by the client will be populated.

If you change the name of a field on the server side, you can still make a call, but the old name on the client side will not be populated.

The same applies if the composite type is passed as an argument or a return type.

17. Performance

You can read about performance on these sites:

weblog.west-wind.com
blogs.msdn.microsoft.com

18. Testing

Dependency injection (with Unity)

This article on MSDN describes details how to use Dependency Injection with WCF

Install Unity Nuget package
(it will add 3 Microsoft.Practices.Unity.*.dlls and Microsoft.Practices.ServiceLocation.dll)

Assuming you have a class that connects to an external repository (e.g. a database) and you want to mock the call for testing.

C#
public interface IExternalRepository
{
	int GetData();
}

public class ExternalRepository : IExternalRepository
{
	public int GetData()
	{
		int result = // read from a database
		return result;
	}
}
and a service depending on the repository

C#
public class MyUnityService : IWcfServiceSimple
{
	public string GetData()
	{
		return _externalRepository.GetData();
	}
}
There are 2 options how to let unity to inject the classes:

1. Create Dependency Injection Factory with static constructor and add contructor to EACH dependency class

C#
using Microsoft.Practices.Unity;
public class DependencyFactory
{
	private static IUnityContainer _container { get; set; }
	
	static DependencyFactory()
	{
		_container = new UnityContainer();
		container.RegisterType<IExternalRepository, ExternalRepository>();
	}

	public static T Resolve<T>()
	{
		T result = default(T);
		if (_container.IsRegistered(typeof(T)))
		{
			result = _container.Resolve<T>();
		}
		return result;
	}
}
and add static constructors to the WCF service

C#
public class MyUnityService : IWcfServiceSimple
{
	private readonly IExternalRepository _externalRepository;

	public MyUnityService() : this(DependencyFactory.Resolve<IExternalRepository>())
	{
	}

	public MyUnityService(IExternalRepository externalRepository)
	{
		_externalRepository = externalRepository;
	}
	
	public string GetData()
	{
		return _externalRepository.GetData();
	}
}
The example above demonstrates what happens behind the scene in the option #2.

2. Use Factory attribute in .svc file.

XML
<%@ ServiceHost Language="C#" Debug="true" Factory="WcfServiceSimpleNs.WcfServiceHostFactory" 
  Service="WcfServiceSimpleNs.WcfServiceSimple2" CodeBehind="WcfServiceSimple2.svc.cs"  %>
This requires to write a class inherited from ServiceHost

C#
public partial class WcfServiceHost : ServiceHost
{
	public WcfServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
		: base(container.Resolve(serviceType), baseAddresses)
	{
	}

	public WcfServiceHost(IUnityContainer container, Type serviceType)
		: base(container.Resolve(serviceType))
	{
	}
}  
and the factory inherited from ServiceHostFactory

C#
public class WcfServiceHostFactory : ServiceHostFactory
{
	private readonly IUnityContainer _container;

	public WcfServiceHostFactory()
	{
		_container = new UnityContainer();
		_container.RegisterType<IExternalRepository, ExternalRepository>();
	}

	protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
	{
		return new WcfServiceHost(_container, serviceType, baseAddresses);
	}
}
The service must be marked with

C#
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class WcfServiceSimple2 : IWcfServiceSimple2
{
}
In both cases, when the WCF service class gets instatiated, the dependency classes (ExternalRepository) will be injected.

The second case does not require to write special constructors for each dependency class.

19. Security

Security Architecture (MSDN)

How to: Authenticate with a User Name and Password (MSDN)
Message Security User Name (MSDN - Example of console client with IIS hosted service)

Turn off authentication (in config)

When authentication is not required, it can be turn off

XML
<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="CustomBinding">
        <security mode="None">
          <message establishSecurityContext="false"/>
          <transport clientCredentialType="None"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  
  <service>
    <endpoint 
        ...
        binding="wsHttpBinding"
        bindingConfiguration="CustomBinding" 
        >
    </endpoint>
  </service>  
....
<system.serviceModel>

Using SSL

Configure IIS to enable SSL. See IIS topic.

1. Create binding behavior for https

XML
<bindings>
  <wsHttpBinding>
    <binding name="secureBinding">
      <security mode="Transport">
        <transport clientCredentialType="None" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
and refer to this behavior from your endPoint

2. Enable https

XML
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpsGetEnabled ="True" />
    </behavior>
  </serviceBehaviors>
</behaviors>
3. Update address in your client to use https

WCF: install certificate in local machine storage

The standard installation with double click on the certificate file is not the right installation procedure if you need a certificate be accessible by a service. The it is necessary:
Start mmc
Go to File / Add/Remove Snap-in...
Double click on Certificates
Select Computer account, Next, Finish, OK
In Console Window right click on Certificates/Personal/Certificates
Select All Tasks/Import
Select your certificate file from

ASP.net roles configuration in Visual Studio 2013

MSDN Article As the menu Website | ASP.NET Configuration is not available in Visual studio 2013, you can invoke the configuration web site manually:
Start IIS express (not as admin) - works with .net 4
iisexpress.exe /path:C:\Windows\Microsoft.NET\Framework\v4.0.30319\ASP.NETWebAdminFiles /vpath:"/ASP.NETWebAdminFiles" /port:8082 /clr:4.0 /ntlm

Open ASP configuration (d:\mySolutionFolder is the path where .sln is located)
http://localhost:8082/asp.netwebadminfiles/default.aspx?applicationPhysicalPath=d:\mySolutionFolder\&applicationUrl=/
You will be ask to enter your Windows credentials. If you are logged to the domain, your full user name will look like "domainName\userName"

If you see the error (probably after VS 2015 installed):
Compiler Error Message: CS0122: 'System.Configuration.StringUtil' is inaccessible due to its protection level

Replace Line 989 in C:\Windows\Microsoft.NET\Framework\v4.0.30319\ASP.NETWebAdminFiles\WebAdminPage.cs

string appId = (String.Concat(appPath, appPhysPath).GetHashCode()).ToString("x", CultureInfo.InvariantCulture);

20. WCF: Assign certificate to client in code

C#
using System.Security.Cryptography.X509Certificates;

var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificatesFound = store.Certificates.Find(X509FindType.FindBySubjectName, (object)"MyCertificateName", true);
store.Close();
channelFactory.Credentials.ClientCertificate.Certificate = certificatesFound[0];

21. WCF: Add http header to request

Adding a header to request requires to implement IClientMessageInspector and IEndpointBehavior

C#
public class HttpHeaderEndpointBehavior : IEndpointBehavior
{
	private readonly IDictionary<string, string> _headers;

	public HttpHeaderEndpointBehavior(IDictionary<string, string> headers)
	{
		_headers = headers;
	}

	public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
	{
		var inspector = new HttpHeaderClientMessageInspector(_headers);
		clientRuntime.MessageInspectors.Add(inspector);
	}

	// implementation of abstract nmethods
	public void Validate(ServiceEndpoint endpoint) { }
	public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
	public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
}

public class HttpHeaderClientMessageInspector : IClientMessageInspector
{
	private readonly IDictionary<string, string> _headers;

	public HttpHeaderClientMessageInspector(IDictionary<string, string> headers)
	{
		_headers = headers;
	}

	public object BeforeSendRequest(ref Message request, IClientChannel channel)
	{
		HttpRequestMessageProperty httpRequestMessage;
		object httpRequestMessageObject;

		if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
		{
			httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
			if (httpRequestMessage != null)
			{
				foreach (var h in _headers)
				{
					httpRequestMessage.Headers[h.Key] = h.Value;
				}
			}
		}

		return null;
	}

	public void AfterReceiveReply(ref Message reply, object correlationState) { }
}


// add header to channel factory before creating the channel
// HttpHeaderEndpointBehavior will be called before each request

var headerDict = new Dictionary<string, string>();
headerDict.Add("MyHeaderKey", "MyHeaderValue");
facadeChannelFactory.Endpoint.Behaviors.Add(new HttpHeaderEndpointBehavior(headerDict));