Custom Tokens Over Non-HTTP Transports by Mark Seemann
About a year ago, one of my readers asked me about how to make custom tokens work over TPC in WCF. Here's the question again:
"i'm trying to implement the CustomToken over tcp. The original used the SymmetricSecurityBindingElement and the transport http, this works fine, but when i change URI's and and the transport, it gives an error saying:
"Binding 'CustomBinding' doesn't support creating any channel types. This often indicates that the BindingElements in a CustomBinding have been stacked incorrectly or in the wrong order. A Transport is required at the bottom of the stack. The recommended order for BindingElements is: TransactionFlow, ReliableSession, Security, CompositeDuplex, OneWay, StreamSecurity, MessageEncoding, Transport."
As it turns out, this seems to be a general issue with more transports than just TCP - at least, I've seen the exact same behavior for the Named Pipes transport.
When I originally received the question, it seemed that no-one knew the answer, and neither did I. Now, about a year later, I've managed to find a solution, and it's really simple.
If you build up your CustomBinding in code, all you need to do is set the TransferMode property to Streamed:
var pipeTransport = new NamedPipeTransportBindingElement(); pipeTransport.TransferMode = TransferMode.Streamed;
In this example, I'm setting the property on a Named Pipe transport, but you can do exactly the same with a TCP transport.
Although I wasn't able to find any documentation to that effect, experimentation seems to indicate that you can also set the property in a .config file (at least, it works on my computer):
<namedPipeTransport transferMode="Streamed" />
I will not claim that I fully understand this fix/workaround, or that it applies in every situation, but I hope that it might prove helpful to some of my readers some day.