Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

WCF 4.0 Configuration Updates

4.94/5 (12 votes)
3 Oct 2012CPOL5 min read 44.6K   451  
This article describes the WCF 4.0 configuration model updates.

Introduction

Windows Communication Foundation (WCF) is a framework for building service-oriented applications. It allows developers to configure services using configuration files or code. Though the configuration settings can be defined through code, it would be easier after being deployed for administration if we put these settings in a configuration file. But when the configuration file becomes too large, the pain comes in. Usually the WCF Configuration Schema is complex and provides user with many hard to find features. WCF 4.0 comes with new features “Simplified Configuration” to remove this pain through support for default endpoints, binding and behavior configurations. In this article, I am going to introduce WCF 4.0 configuration model updates. I will explain step by step the followings features:<o:p>

Default Endpoints

WCF 3.x required at least one endpoint, otherwise you would get an exception. In WCF 4.0, services originate with default endpoints, that is, runtime automatically adds one or more default endpoints making the service available without any configuration. The runtime will add default endpoints based on the combination of each service contract implemented by the service and base addresses. Say, if the service implements a single contract and the host is configured with a single base address, the runtime will add a single default endpoint. If we configure the host with two base addresses and the service implements a single contract, it will add two default endpoints. As an example, please have a look at the code given below.

Service Contract

C#
[ServiceContract]
public interface IMessageService
{
   [OperationContract]
   string GetMessage(string submittedMsg);
} 

Implementation

C#
public class MessageService:IMessageService
{
   public string GetMessage(string submittedMsg)
   {
      if(!string.IsNullOrEmpty(submittedMsg))
      {
          return submittedMsg;
      }
         return string.Empty;
    }
}   

Host Configuration

C#
using(var host=new ServiceHost(typeof(MessageService),
                new Uri("net.tcp://localhost/netTCP"),
                new Uri("http://localhost/http")))
            {             
                host.Open();
                host.Description.Endpoints.ToList().ForEach((endPoint)=> 
				Console.WriteLine(endPoint.ListenUri));
                Console.WriteLine("Press Enter to Exit");
                Console.Read();
            }   

In the above code portion, we see that the service implements a single contract. And host is configured with two base addresses, one for TCP and the other for Http. In this case, runtime will automatically add two default endpoints.

WCF decides which binding to use for a particular based address depending on a default protocol mapping between transport protocol schemes and the built-in WCF bindings. The default protocol mapping is found in the .NET 4 machine.config.comments file and it looks like this:

C#
<system.serviceModel>
 <protocolMapping>
   <add scheme="http" binding="basicHttpBinding" bindingConfiguration="" />
   <add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration=""/>
   <add scheme="net.pipe" binding="netNamedPipeBinding" bindingConfiguration=""/>
   <add scheme="net.msmq" binding="netMsmqBinding" bindingConfiguration=""/>
 </protocolMapping>
 ...

We can override these mappings at the machine level by adding this section to machine.config and changing the mapping for each protocol scheme. Or if we'd only like to override it within the room of an application, we can override this section within our application/web configuration file. In our demo project, we map the Http to wsHttpBinding.

C#
<protocolMapping>
   <remove scheme="http"/>
   <add scheme="http" binding="wsHttpBinding"/>
</protocolMapping>  

Once WCF determines which binding to use via the protocol mapping table, it uses the default binding configuration when configuring the default endpoint.

Default Bindings

We can define default binding by simply defining the binding without a name. This binding will take consequence for anything not assigned a specific binding. We can define it in a different scope like machine.config. For example, if we add the following app.config file to our demo application, the default HTTP endpoints will pick up this default configuration, which enables MTOM.

C#
<bindings>
   <wsHttpBinding>
     <binding  messageEncoding="Mtom"/>      
   </wsHttpBinding>
</bindings>  

Default Behaviors

In WCF 3.x, we have to define named behavior configurations that we explicitly apply to services and endpoints through the “behaviorConfiguration” attribute. Likewise default binding, we can also define default behavior by simply defining the behavior without a name, which can shorten stuff when we need to share a standard default behavior configuration across all services or endpoints. The following code portion turns on service metadata for any services that don’t come with an explicit behavior configuration.

C#
<serviceBehaviors>
  <behavior>
     <serviceMetadata httpGetEnabled="true"/>
  </behavior>
</serviceBehaviors>  

Standard Endpoints

A standard endpoint allows the user to simplify endpoint definitions by using a single property to describe an address, binding and contract combination with additional properties associated to it. WCF 4.0 also comes with several preconfigured standard endpoints which cover some of the most common usage scenarios by simply reusing them as-is without change. For example, in the case of a MEX endpoint, we will always need to specify IMetadataExchange for the service contract and are most likely to choose HTTP. So instead of doing manually, WCF provides a standard endpoint definition for metadata exchange called “mexEndpoint” that’s easy to use. We can refer to the standard endpoints by name using the kind attribute.

C#
<services>
      <service name="MessageService">
         <endpoint kind="mexEndpoint" address="/mex"/>
      </service>
</services>  

File-less Activation

Although .svc files make it easy to expose WCF services, with WCF 4.0 we no longer need physical .svc file to activate services. Instead, we can define a virtual mapping in config. The following example shows how to configure an activation endpoint:

C#
<services>
   <service name="FileLessActivationDemo.NoSvc">
      <endpoint kind="webHttpEndpoint" 
      contract="FileLessActivationDemo.IMessageService"/>
      <endpoint kind="mexEndpoint" address="/mex"/>
   </service>
</services>           

It’s now possible to activate the NoSvc using a relative path of “NoSvc.svc” (relative to the base address of the Web application).

Using the Solutions

To see the output of demo application, you need to run Rashim.RND.WCF.ConfigurationModel.Server first and then run Rashim.RND.WCF.ConfigurationModel.Client. In the app.config file of Rashim.RND.WCF.ConfigurationModel.Server, you will see some new things that I have already described above. The configuration file looks like below:

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <protocolMapping>
      <remove scheme="http"/>
      <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding  messageEncoding="Mtom"/>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="MessageService">
        <endpoint kind="mexEndpoint" address="/mex"/>
      </service>
    </services>
  </system.serviceModel>
</configuration> 

To see the output of File-less activation, please run the project FileLessActivationDemo and you will see the directory list where there is no NoSvc.svc file. But if you write in the addressbar like http://localhost...../NoSvc.svc, you will see that the NoSvc.svc is activated. The configuration file for this application looks like:

XML
 <?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="True">
      <serviceActivations>
        <add service="FileLessActivationDemo.NoSvc" relativeAddress="NoSvc.svc"/>
      </serviceActivations>
    </serviceHostingEnvironment>
    <protocolMapping>
      <remove scheme="http"/>
      <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="FileLessActivationDemo.NoSvc">
        <endpoint kind="webHttpEndpoint" contract="FileLessActivationDemo.IMessageService"/>
        <endpoint kind="mexEndpoint" address="/mex"/>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration> 

References

That's It

That's it for now. I hope this article will help you to know updates of WCF 4.0 configuration model.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)