Bigger Rock, But Still!!!

OK, after the smaller rock, I got a slightly bigger rock now… but I still think it’s a stupid mistake. I hope you guys don’t make the same one.

Instead of a internal setter, I removed the setter at all. Well, it didn’t serialize with my data at all! Everything else came through correctly but the properties without setter.

public class Employee
    public int ID { get; }
    public string Firstname { get; set; }

What basically happens here is WCF creates XML schema for classes it needs to return as a response. The XML schema it creates is similar to C# class, but without C#-specific syntax like access modifier. The purpose of this is so that WCF can serialize the data and serve it as SOAP response, which is XML-based. The creation of the schema, ostensibly, ignores properties without setter.

Slightly bigger rock, but I still got tripped. Oh well..


It’s The Small Rock, Agggh!!

I have this stupid mistake that I hope none of you would ever make.

I am building a WCF service and one of the DTOs is something like this:

public class Employee
    public int ID { get; internal set; }
    public string Firstname { get; set; }

On the ‘other’ side (client), I can’t set my Employee’s ID… Hours of debugging turned to “dooohhhh” moment when I realized the setter was in fact internal. Internal is internal, access modifier that can’t be accessed from outside library. Easily miss the basic when you deal with higher level stuff.

It’s the small, tiny rock that trips you. Aggh!

Configure IIS-Hosted WCF to Run On SSL

It’s possible to run IIS-hosted WCF locally, with SSL.

Here’s the full guide: Configure an IIS-hosted WCF service with SSL.

To generate self-signed trusted SSL certificate, see How to Create Valid and Trusted SSL Certificate (Wildcard) for Development.

Just in case you need it, for web application to run on IIS Express with SSL, see: Enable SSL in IIS Express

WCF Message and Transport Security


The encryption takes place when the message is about to send over, at transport layer.
Depends on the transport protocol, normally require HTTPS (if send over HTTP).


The encryption takes place on the message itself, before it is sent.
For most part, it’s transport-independent.
More flexibility, you can use any type of security credential as long as client and service agree.


        <binding name="wsHttpEndpointBinding">
          <security mode="Transport">
          <!--<security mode="Message">

Options the security mode are:

  • None
  • Message
  • Transport
  • Both
  • TransportWithMessageCredential
  • TransportCredentialOnly

More info on: What the difference between transport and message security?

Differences Between BasicHttpBinding and WsHttpBinding

TLDR: Security: BasicHttp sends request in plain text and WsHttp implements WS-Security. Protocol: in BasicHttp, SOAP 1.1 and WsHttp, SOAP 1.2 (it also supports full WS federation). State management: BasicHttp is stateless, WsHttp supports state management.

Criteria BasicHttpBinding WsHttpBinding
Security support This supports the old ASMX style, i.e. WS-BasicProfile 1.1. This exposes web services using WS-* specifications.
Compatibility This is aimed for clients who do not have .NET 3.0 installed and it supports wider ranges of clients. Many of the clients like Windows 2000 still do not run .NET 3.0. So older version of .NET can consume this service. As its built using WS-* specifications, it does not support wider ranges of client and it cannot be consumed by older .NET version less than 3 version.
Soap version SOAP 1.1 SOAP 1.2 and WS-Addressing specification.
Reliable messaging Not supported. In other words, if a client fires two or three calls you really do not know if they will return back in the same order. Supported as it supports WS-* specifications.
Default security options By default, there is no security provided for messages when the client calls happen. In other words, data is sent as plain text. As WsHttBinding supports WS-*, it has WS-Security enabled by default. So the data is not sent in plain text.
Security options
  • None
  • Windows – default authentication
  • Basic
  • Certificate
  • None
  • Transport
  • Message
  • Transport with message credentials

Source: Difference between BasicHttpBinding and WsHttpBinding

MSDN resource has complete list of the differences between bindings.

An Unsecured or Incorrectly Secured Fault Was Received From The Other Party


The inner FaultException goes something like: System.ServiceModel.FaultException: The message could not be processed because the action ‘; is invalid or unrecognized.

It’s caused by WCF service configured to not communicate in WS-SecureConversation while the client is. Or vice versa. In my case, the client is an ASP.NET MVC 4 application that is trying to pass token (identity delegation) over to a WCF 4.5 service through WSTrustChannelFactory protocol.

Both of the client and the service must be configured to use same security context. If you want to turn WS-SecureConversation off, turn off on both config. Same applies to turning on WS-SecureConversation.

        <security mode="TransportWithMessageCredential">
            <message establishSecurityContext="false" />

WCF Client Config Template with Identity Delegation (WSTrust)

A minimal config for a client (for example, ASP.NET MVC application, ASP.NET Web Form application, or another WCF service application), that is a relying party to WIF (or any STS), to consume a WCF service (SOAP) using Identity Delegation (with WSTrust protocol). Identity Delegation allows the client to call WCF service and pass in the claims as if it’s being called by the user of the client. Compare Identity Delegation to Trusted Subsystem.

This config is auto-generated with “Add Service Reference” wizard from WCF service config in WCF Config Template for Identity Delegation with WIF.

This config DOES NOT include setting integrating the client with WIF. For example of this, see WIF 3.5 Relying Party Config Template.

Note that:
http://localhost:11000 is the Secure Token Service (STS) URL.
http://localhost:58829 is service’s endpoint address.

<?xml version="1.0" encoding="utf-8" ?>
                <binding name="WS2007FederationHttpBinding_IService">
                            <issuer address="http://localhost:11000/Issue.svc" binding="ws2007HttpBinding"
                                    <dns value="IdentityTKStsCert" />
                            <issuerMetadata address="http://localhost:11000/Issue.svc/mex" />
                                <trust:SecondaryParameters xmlns:trust="">
                                    <trust:KeyType xmlns:trust=""></trust:KeyType>
                                    <trust:KeySize xmlns:trust="">256</trust:KeySize>
                                    <trust:KeyWrapAlgorithm xmlns:trust=""></trust:KeyWrapAlgorithm>
                                    <trust:EncryptWith xmlns:trust=""></trust:EncryptWith>
                                    <trust:SignWith xmlns:trust=""></trust:SignWith>
                                    <trust:CanonicalizationAlgorithm xmlns:trust=""></trust:CanonicalizationAlgorithm>
                                    <trust:EncryptionAlgorithm xmlns:trust=""></trust:EncryptionAlgorithm>
                <binding name="http://localhost:11000/Issue.svc">
                        <message clientCredentialType="Certificate" negotiateServiceCredential="false" />
            <endpoint address="http://localhost:58829/Service.svc" binding="ws2007FederationHttpBinding"
                contract="ServiceReference.IService" name="WS2007FederationHttpBinding_IService">
                    <certificate encodedValue="AwAAAAEAAAAUAAAAQKHSYiv" />

To create ChannelFactory and pass in the secured token from the client:

// Get the token
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory( stsBinding, stsAddress );
WSTrustChannel channel = (WSTrustChannel) trustChannelFactory.CreateChannel();
RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = new EndpointAddress(serviceAddress);
RequestSecurityTokenResponse rstr = null;
SecurityToken token = channel.Issue(rst, out rstr);

// Use the token, pass in to WCF service
IHelloService serviceChannel = channelFactory.CreateChannelWithIssuedToken<IHelloService>( token ); serviceChannel.Hello(“Hi!”);

Additional resource: MSDN WSTrustChannelFactory and WSTrustChannel