Talking to a non-WCF webservice is like a box of chocolates... you never know what you're going to get. After solving the issue mentioned in my previous blog post, I had another problem. For some reason the service didn't expect a <wsa:ReplyTo> element if the value was anonymous. Later on the other party adjusted the service so it actually worked as expected from WCF, but in the mean time I did write a message inspector to solve the problem. Besides solving the problem it also is a nice little example of a message inspector.
public class RemoveAnonymousReplyToMessageInspector : IClientMessageInspector
{
private const string ReplyToNode = "ReplyTo";
private const string WSAddressingNamespace = "http://www.w3.org/2005/08/addressing";
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{} // Not used for this scenario.
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{ // This method is called before the request is sent. You can read/manipulate the message here. // If you're using signing or encryption, that is done after this, this is the // unencrypted/unsigned mesage.
request = RemoveAnonymousReplyTo(request);
return null;
}
private Message RemoveAnonymousReplyTo(Message message)
{
if (message.Headers.ReplyTo.IsAnonymous == true)
{
int index = message.Headers.FindHeader(ReplyToNode, WSAddressingNamespace);
message.Headers.RemoveAt(index);
}
return message;
}
}
To use this, you'll need to create a class implementing the IEndpoint behavior and add the MessageInspector in ApplyClientBehavior, as follows:
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
RemoveAnonymousReplyToMessageInspector inspector = new RemoveAnonymousReplyToMessageInspector();
clientRuntime.MessageInspectors.Add(inspector);
}