I am trying to use IDispatchMessageInspector in a WCF service implementation to access custom header values.
Something like:
public class MyService :
I'm using IClientMessageInspector for same goal. Here is how you can apply them from code:
var serviceClient = new ServiceClientClass(binding, endpointAddress);
serviceClient.Endpoint.Behaviors.Add(
new MessageInspectorEndpointBehavior());
///
/// Represents a run-time behavior extension for a client endpoint.
///
public class MessageInspectorEndpointBehavior : IEndpointBehavior
where T: IClientMessageInspector, new()
{
///
/// Implements a modification or extension of the client across an endpoint.
///
/// The endpoint that is to be customized.
/// The client runtime to be customized.
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new T());
}
///
/// Implement to pass data at runtime to bindings to support custom behavior.
///
/// The endpoint to modify.
/// The objects that binding elements require to support the behavior.
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// Nothing special here
}
///
/// Implements a modification or extension of the service across an endpoint.
///
/// The endpoint that exposes the contract.
/// The endpoint dispatcher to be modified or extended.
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// Nothing special here
}
///
/// Implement to confirm that the endpoint meets some intended criteria.
///
/// The endpoint to validate.
public void Validate(ServiceEndpoint endpoint)
{
// Nothing special here
}
}
And here is sample implementation of MessageInspector I'm using to pass client version to server, and retrieve server version in custom headers:
///
/// Represents a message inspector object that can be added to the MessageInspectors collection to view or modify messages.
///
public class VersionCheckMessageInspector : IClientMessageInspector
{
///
/// Enables inspection or modification of a message before a request message is sent to a service.
///
/// The message to be sent to the service.
/// The WCF client object channel.
///
/// The object that is returned as the argument of
/// the method.
/// This is null if no correlation state is used.The best practice is to make this a to ensure that no two
/// objects are the same.
///
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request.Headers.Add(new VersionMessageHeader());
return null;
}
///
/// Enables inspection or modification of a message after a reply message is received but prior to passing it back to the client application.
///
/// The message to be transformed into types and handed back to the client application.
/// Correlation state data.
public void AfterReceiveReply(ref Message reply, object correlationState)
{
var serverVersion = string.Empty;
var idx = reply.Headers.FindHeader(VersionMessageHeader.HeaderName, VersionMessageHeader.HeaderNamespace);
if (idx >= 0)
{
var versionReader = reply.Headers.GetReaderAtHeader(idx);
while (versionReader.Name != "ServerVersion"
&& versionReader.Read())
{
serverVersion = versionReader.ReadInnerXml();
break;
}
}
ValidateServerVersion(serverVersion);
}
private static void ValidateServerVersion(string serverVersion)
{
// TODO...
}
}
public class VersionMessageHeader : MessageHeader
{
public const string HeaderName = "VersionSoapHeader";
public const string HeaderNamespace = "";
private const string VersionElementName = "ClientVersion";
public override string Name
{
get { return HeaderName; }
}
public override string Namespace
{
get { return HeaderNamespace; }
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteElementString(
VersionElementName,
Assembly.GetExecutingAssembly().GetName().Version.ToString());
}
}