How to add custom policy assertions to a WCF service without using a custom binding

Recently I have been trying to work with the ws policy standard to add information to our service WSDLs. WCF has an extension point for doing just that, you can read a really good example of this WCF extension here. One limitation of this method is that you must use a binding of type ‘custom’.

It is worth mentioning at this point there is a really confusing issue with WCF bindings in that there is a pre-defined binding called ‘customBinding’ that gives you control over all the binding elements that make up a WCF binding. This allows you to completely tailor the binding at configuration time. You can also create your own binding type (in code) and allow this to be used at configuration time (the method explained in this post).

So what is the problem with using a ‘customBinding’? – Well we also require our services to use 2 possible bindings either basicHttpBinding or WSHttpBinding. We could create a ‘customBinding’ that mimics basic (or ws respectively) with the addition of a ‘PolicyExporter’ Binding element. However without digging down into the details of these 2 bindings how do we know what settings to use for the ‘customBinding’. This would also lead to even more complicated web.config files. We could also easily break the service at configuration time by changing part of the customBinding.

So what do we do? – Create 2 new bindings in code, each of which derives from either basicHttpBinding or WsHttpBinding, as well as adding a ‘PolicyExporter’ binding element (or any other custom binding elements we want). We then create some other classes that allow this binding to be used at configuration time. It is possible to manually create these classes, but there is also a tool that creates these classes based on a binding (saving time etc).

Step 1 – Create the binding
In a class library that can be referenced from the web.config (we have a dll for all our WCF extensions). Define a class that inherits from the binding, and overrides ‘CreateBindingElements’ like so:

 public class CustomBasicBinding:BasicHttpBinding
{
    public CustomBasicBinding():base()
    {
	//you can even define standard binding settings here!
        base.Security.Mode = BasicHttpSecurityMode.Transport;
	base.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;        
    }

    public override BindingElementCollection CreateBindingElements()
    {
        BindingElementCollection bindingEls = base.CreateBindingElements();
	//note that PolicyExporterBindingElement is a custom type defined elsewhere
        bindingEls.Insert(0,new PolicyExporterBindingElement(new GetPoliciesFromConfig()));
        return bindingEls;
    }      
}

Step  2 – Use the tool to generate the other classes

The WCF samples download includes a useful tool to create these other classes. Download the samples, locate the source for the tool (TechnologySamples\Tools\ConfigurationCodeGenerator\CS), build the .exe, copy the exe to wherever the .dll for your custom binding is, use a command line and run the tool:

ConfigurationCodeGenerator.exe /sb:CustomBasicBinding /dll:<dll filename>

Step 3 – Copy generated code

navigate to the location of the dll, there should be one file  ‘CodeToAddTo<BindingName>‘  copy the contents of this file into your binding code. Copy the remaining generated files to your project location.

Step 4 – Use the new binding for your service

Modify the web.config for your service (either manually or using the WCF configuration tool). Add a ‘binding extension’, using the WCF config tool you can use a wizard to locate the dll and find the binding type (if you can’t see it in the dialog you’ve done something wrong!). Choose a name for the binding (used elsewhere in the config).

For any service endpoint that should use this binding, choose your new binding type as the binding for the service. If necessary you should also be able to create a BindingConfiguration (thanks to the generated code).

<extensions>
	<bindingExtensions>
		<add name="CustomBasic" type="Namespace.CustomBasicBindingCollectionElement, namespace, Version=1.0.0.1, Culture=neutral, PublicKeyToken='KEY'" />
	</bindingExtensions>
</extensions>
...
...
<services>
	<service code cut for clarity>
		<endpoint 
			binding="CustomBasicBinding"
			...
		>
	</service>
</services>
Advertisements

About Alex McMahon

I am a software developer, interested in .net, agile, alt.net. I've previously specialised with .net 3.0 technologies like WCF, whereas now I am trying to specialise in agile development and best practice and patterns. I am obsessed with looking at the latest technologies, tools, and methods, and trying them out. I am currently employed by Rockwell Collins in the UK.
This entry was posted in .net, wcf, wcf behaviors, web service. Bookmark the permalink.

2 Responses to How to add custom policy assertions to a WCF service without using a custom binding

  1. AJ says:

    Hi…
    you define CustomBasic as name for the binding extension and define CustomBasicBinding as binding for your endpoint. I would believe that it should be the same name in both cases.

  2. Adam Pritchard says:

    Thanks for your article, a very informative read. I’ve been trying to create a CustomBinding that uses WebHttpBinding as a template and then adds a custom ContentTypeMapper to ensure all communication is raw and no attempted conversion to XML/JSON takes place.

    I’ve created a class library called RawWebHttpBinding and I’ve added the following two classes to it..

    namespace RawWebHttpBinding
    {
    public class RawWebContentTypeMapper : WebContentTypeMapper
    {
    public override WebContentFormat GetMessageFormatForContentType(string contentType)
    {
    return WebContentFormat.Raw;
    }
    }

    public class RawWebHttpBinding : CustomBinding
    {
    public RawWebHttpBinding()
    : base(new WebHttpBinding())
    {
    SetupRawWebContentTypeMapper();
    }

    private void SetupRawWebContentTypeMapper()
    {
    WebMessageEncodingBindingElement mebe = Elements.Find();
    mebe.ContentTypeMapper = new RawWebContentTypeMapper();
    }
    }
    }

    I’ve tried adding this binding to my web.config using the Microsoft Service Configuration Editor but my types are not appearing in the “Add” dialog under the binding extensions configuration section.

    What do I need to do to make these visible?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s