I have an environment with SOA architecture spans a number of WCF services. Some of these services need to identity its clients. Based on different client's identity or scope, the service needs to run different conditional code. One way to achieve this functionality is to add a custom http-header in each WCF method call on client side, which will enable WCF service to identity the client for any given request.
In this exmaple, I will add a custom http-header named Client-Id
, using custom implemenation of IClientMessageInspector
interace.
You need to create two classes
-
One is
CustomHeaderEndpointBehavior
to implmentIEndpointBehavior
interface. -
Second is
CustomHeaderMessageInspector
which implements theIClientMessageInspector
interface.
The CustomHeaderEndpointBehavior
class will add our custom CustomHeaderMessageInspector
to ClientMessageInspectors
collection for clientRuntime
object.
clientRuntime.ClientMessageInspectors.Add(customHeaderMessageInspector);
In CustomHeaderMessageInspector
class, we can add the custom header in BeforeSendRequest()
method.
Complete code listing for CustomHeaderMessageInspector
class is:
public class CustomHeaderMessageInspector : IClientMessageInspector { private const string CLIENT_ID_HTTP_HEADER = "Client-Id"; private string _clientId; public CustomHeaderMessageInspector(string clientId) { this._clientId = clientId; } public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { } public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) { HttpRequestMessageProperty httpRequestMessage; object httpRequestMessageObject; if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject)) { httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty; if (string.IsNullOrEmpty(httpRequestMessage.Headers[CLIENT_ID_HTTP_HEADER])) { httpRequestMessage.Headers[CLIENT_ID_HTTP_HEADER] = this._clientId; } } else { httpRequestMessage = new HttpRequestMessageProperty(); httpRequestMessage.Headers.Add(CLIENT_ID_HTTP_HEADER, this._clientId); request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage); } return request; } }
Code listing for CustomHeaderEndpointBehavior
class is:
public class CustomHeaderEndpointBehavior : IEndpointBehavior { private string _clientId; public CustomHeaderEndpointBehavior(string clientId) { this._clientId = clientId; } public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) { CustomHeaderMessageInspector inspector = new CustomHeaderMessageInspector(this._clientId); clientRuntime.ClientMessageInspectors.Add(inspector); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } }
When calling the service methods on the client side, you can simply add the custom EndpointBehavior
(CustomHeaderEndpointBehavior
)
on the service client instance object.
ServiceReference1.Service1Client service1Client = new ServiceReference1.Service1Client(); var requestInterceptor = new CustomHeaderEndpointBehavior(); service1Client.Endpoint.EndpointBehaviors.Add(requestInterceptor);
Now you can call any service method, the custom htpp-header will be automatically added to each request.