Wednesday, July 24, 2013

WCF Template auto-redirects

Just a post to consolidate the various information on the net regarding preventing WCF from redirecting upon a request passing or not passing a trailing slash when it differs from the UriTemplate declared on the service.

The bits needed....

First of a message inspector to check for the wcf redirect property and remove it from the Message.
internal class 307MessageInspector :IDispatchMessageInspector
{
private const String RedirectPropertyName = "WebHttpRedirect";
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
// This explicitly removes WCF generated redirects caused by added/removed slash from uri templates.
if (request.Properties.ContainsKey(RedirectPropertyName))
{
request.Properties.Remove(RedirectPropertyName);
}
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
// Do nothing as we dont want to override anything in the pipeline.
}
}

Next you need to implement a custom contract behavior to make sure its applied high enough up the pipeline to prevent WCF doing its usual redirect.
internal class 307ContractBehavior : IContractBehavior
{
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
// Not required
}
// Adds the 307MessageInspector to the contact to prevent 307 redirects on incorrect template match.
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.MessageInspectors.Add(new 307MessageInspector());
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// Not required
}
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// Not required
}
}

Finally add it to your service host in the OnOpening override.
protected override void OnOpening()
{
base.OnOpening();
Log.Debug("Applying prevent 307 redirect behavior");
endpoint.Contract.Behaviors.Add(new 307ContractBehavior());
}
And you should now find you no longer get redirected when passing an incorrect url to your WCF application.

No comments:

Post a Comment