Implementing Automatic Custom HTTP Header Addition for All WCF Calls

Dec 01, 2025 · Programming · 10 views · 7.8

Keywords: WCF | HTTP headers | message inspector

Abstract: This article provides an in-depth technical analysis of automatically adding custom HTTP headers to every WCF client call. By examining the IClientMessageInspector interface implementation and the use of HttpRequestMessageProperty, it presents a comprehensive solution. The discussion includes comparisons with alternative approaches and considerations for Compact Framework compatibility.

Introduction

In distributed system architectures, Windows Communication Foundation (WCF) serves as a critical service-oriented framework for enterprise application development. Practical scenarios often require passing additional contextual information between clients and servers, such as user identifiers, session tokens, or business-specific metadata. Placing this information in HTTP headers is a common and effective approach, as it avoids interference with service contract definitions while providing necessary context for each call.

Problem Context and Requirements Analysis

Consider a typical WCF service deployment: the service is hosted in a Windows service, with clients including desktop applications and mobile applications based on Compact Framework. Business logic mandates that each service call must carry an identifier that determines the specific behavior of method execution. Manually adding the identifier at each call site is not only tedious but also error-prone, necessitating an automated mechanism.

Core Solution: The IClientMessageInspector Interface

The WCF framework offers powerful extensibility points, with the IClientMessageInspector interface allowing developers to intercept message processing before sending and after receiving. By implementing the BeforeSendRequest method, custom HTTP headers can be added to outgoing request messages.

The following example demonstrates how to add a user-agent header to an HTTP request message:

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["User-Agent"]))
        {
            httpRequestMessage.Headers["User-Agent"] = this.m_userAgent;
        }
    }
    else
    {
        httpRequestMessage = new HttpRequestMessageProperty();
        httpRequestMessage.Headers.Add("User-Agent", this.m_userAgent);
        request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
    }
    return null;
}

This code first checks if an HttpRequestMessageProperty already exists in the request properties. If present, it directly adds or updates the user-agent information in its header collection; otherwise, it creates a new property object and adds it to the request. This approach ensures that header information is correctly attached to each outgoing message.

Endpoint Behavior and Configuration

To activate the message inspector, an endpoint behavior must be created and applied to the client runtime. The behavior can be applied via custom attributes or configuration file extension elements. Below is a simple behavior class definition:

public class CustomHeaderBehavior : IEndpointBehavior
{
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new CustomMessageInspector());
    }
    // Other method implementations omitted
}

In the configuration file, the behavior can be declared and used as follows:

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="customHeaderBehavior" type="Namespace.CustomHeaderBehaviorExtensionElement, Assembly" />
    </behaviorExtensions>
  </extensions>
  <behaviors>
    <endpointBehaviors>
      <behavior name="customBehavior">
        <customHeaderBehavior />
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

Alternative Approaches and Comparative Analysis

Beyond message inspectors, another common method involves explicitly adding message headers in code using OperationContextScope. For example:

using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
{
    MessageHeader<string> header = new MessageHeader<string>("secret message");
    var untyped = header.GetUntypedHeader("Identity", "http://www.my-website.com");
    OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
    // Perform WCF calls within this using block
}

The server can read this header as follows:

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string identity = headers.GetHeader<string>("Identity", "http://www.my-website.com");

However, this approach requires developers to manually manage context at each call site, increasing code complexity and maintenance overhead. In contrast, the solution based on IClientMessageInspector offers greater automation and consistency.

Compact Framework Compatibility Considerations

For Windows Mobile applications, WCF clients based on Compact Framework support a limited feature set. According to Microsoft documentation, message inspectors are classified as "Channel Extensibility," which is supported in Compact Framework. This means the above solution can be applied seamlessly to mobile clients without additional adaptation.

Server-Side Handling

On the server side, custom headers in incoming messages can be intercepted and processed by implementing the IDispatchMessageInspector interface. This allows the service to validate or log header information before executing business logic, enabling complete end-to-end context propagation.

Conclusion

By implementing the IClientMessageInspector interface and configuring endpoint behaviors, developers can efficiently automate the addition of custom HTTP headers to all WCF calls. This method not only reduces code duplication but also enhances system maintainability and scalability. For scenarios requiring support for multiple client types, including Compact Framework, this solution provides robust compatibility and consistency.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.