I'd like to convert my current HTTP/HTTPS WCF binding settings to use binary message encoding and I need to do it in code - not in XML configuration. AFAIK it's necessary to create CustomBinding object and set proper BindingElements, but I'm not able to figure out what elements should I use in my scenario.
Main points in my WCF configuration are:
- use HTTP or HTTPS transport depending on configuration (in app.config)
- use username message security
- todo: add binary encoding instead of default text
My current code for setting the binding up (working, but without the binary encoding):
var isHttps = Settings.Default.wcfServiceBaseAddress.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase);
var binding = new WSHttpBinding(isHttps ? SecurityMode.TransportWithMessageCredential : SecurityMode.Message);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
I was trying this code, but it doesn't work - I don't know how to set message security element for username message security:
var custBinding = new CustomBinding();
custBinding.Elements.Add(new BinaryMessageEncodingBindingElement());
//Transport Security (Not Required)
if (isHttps)
{
custBinding.Elements.Add(SecurityBindingElement.CreateUserNameForSslBindingElement());
}
//Transport (Required)
custBinding.Elements.Add(isHttps ?
new HttpsTransportBindingElement() :
new HttpTransportBindingElement());
Anybody knows how to set this up? I tried to search for similar problem/solution, but didn't succeeded...
I almost forgot this question, but here is my custom binding class which works with binary binding over HTTP with username+password validation and also allows to turn GZip compression on...
public class CustomHttpBinding: CustomBinding
{
private readonly bool useHttps;
private readonly bool useBinaryEncoding;
private readonly bool useCompression;
private readonly HttpTransportBindingElement transport;
public CustomHttpBinding(bool useHttps, bool binaryEncoding = true, bool compressMessages = false)
{
this.useHttps = useHttps;
transport = useHttps ? new HttpsTransportBindingElement() : new HttpTransportBindingElement();
useBinaryEncoding = binaryEncoding;
useCompression = compressMessages;
}
public long MaxMessageSize{set
{
transport.MaxReceivedMessageSize = value;
transport.MaxBufferSize = (int) value;
}}
public override BindingElementCollection CreateBindingElements()
{
BindingElement security;
if (useHttps)
{
security = SecurityBindingElement.CreateSecureConversationBindingElement(
SecurityBindingElement.CreateUserNameOverTransportBindingElement());
}
else
{
security = SecurityBindingElement.CreateSecureConversationBindingElement(
SecurityBindingElement.CreateUserNameForSslBindingElement(true));
}
MessageEncodingBindingElement encoding;
if (useCompression)
{
encoding = new GZipMessageEncodingBindingElement(useBinaryEncoding
? (MessageEncodingBindingElement)
new BinaryMessageEncodingBindingElement()
: new TextMessageEncodingBindingElement());
}
else
{
encoding = useBinaryEncoding
? (MessageEncodingBindingElement) new BinaryMessageEncodingBindingElement()
: new TextMessageEncodingBindingElement();
}
return new BindingElementCollection(new[]
{
security,
encoding,
transport,
});
}
}
Try SecurityBindingElement.CreateUserNameOverTransportBindingElement()
instead:
var custBinding = new CustomBinding();
custBinding.Elements.Add(new BinaryMessageEncodingBindingElement());
//Transport Security (Not Required)
if (isHttps)
{
custBinding.Elements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
}
//Transport (Required)
custBinding.Elements.Add(isHttps ?
new HttpsTransportBindingElement() :
new HttpTransportBindingElement());
The SecurityBindingElement has a AllowInsecureTransport property. If you set this to true you can use the HttpTransportBindingElement with message user name and password security.