by Paulo Morgado via Paulo Morgado : C# on 4/26/2007 11:50:50 PM
Yesterday I had to build a custom message encoder to be able to call a legacy POX service with iso-8859-1 encoding.
It turned out that the service had another surprise to me: it needs an HTTP user-agent header.
It's something quite simple to accomplish with WCF. All it's needed is to add the required header to the HTTP request message property of the request message. Something like this:
HttpRequestMessageProperty httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, this.m_userAgent);
requestMessage.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
But I was not willing to pollute my code with this and, besides that, it doesn't look much WCFish having to do this.
Since I don't like to spend too much time trying to figure things out when I know someone who knows it, I asked António Cruz what to do. And the answer was a client message inspector.
With the help of a sample I have built an HTTP user agent client message inspector.
The message inspector is very simple. We just need to implement the IClientMessageInspector Interface.
public class HttpUserAgentMessageInspector : IClientMessageInspector
{
private const string USER_AGENT_HTTP_HEADER = "user-agent";
private string m_userAgent;
public HttpUserAgentMessageInspector(string userAgent)
this.m_userAgent = userAgent;
}
#region IClientMessageInspector Members
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[USER_AGENT_HTTP_HEADER]))
httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER] = this.m_userAgent;
else
httpRequestMessage = new HttpRequestMessageProperty();
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
return null;
#endregion
But this message inspectors are extensions to the client runtime. Such extensions are configured using behaviors. A behavior is a class that changes the behavior of the service model runtime by changing the default configuration or adding extensions (such as message inspectors) to it.
The implementation of a behavior is, also, very simple. We just need to implement the IEndpointBehavior Interface. In this case, since it's a client message inspector only, all we need to implement is the ApplyClientBehavior method.
public class HttpUserAgentEndpointBehavior : IEndpointBehavior
public HttpUserAgentEndpointBehavior(string userAgent)
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
HttpUserAgentMessageInspector inspector = new HttpUserAgentMessageInspector(this.m_userAgent);
clientRuntime.MessageInspectors.Add(inspector);
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
public void Validate(ServiceEndpoint endpoint)
For configuring an endpoint in the application configuration file to use our custom behavior, the service model requires us to create a configuration extension element represented by a class derived from BehaviorExtensionElement.
public class HttpUserAgentBehaviorExtensionElement : BehaviorExtensionElement
public override Type BehaviorType
get
return typeof(HttpUserAgentEndpointBehavior);
protected override object CreateBehavior()
return new HttpUserAgentEndpointBehavior(UserAgent);
[ConfigurationProperty("userAgent", IsRequired = true)]
public string UserAgent
get { return (string)base["userAgent"]; }
set { base["userAgent"] = value; }
This extension must then be added to the service model's configuration section for extensions:
<system.serviceModel>
...
<extensions>
<behaviorExtensions>
<add name="httpUserAgent" type="Pajocomo.ServiceModel.Dispatcher.HttpUserAgentBehaviorExtensionElement, Esi.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
Note: We must use the full assembly qualified name here, otherwise it won't work.
Now we need to apply our behavior extension to a behavior configuration:
<behaviors>
<endpointBehaviors>
<behavior name="LegacyServiceEndpointBehavior">
<httpUserAgent userAgent="test user agent" />
</behavior>
</endpointBehaviors>
</behaviors>
Now we can apply this configuration to our sevice configuration:
<client>
<endpoint
address="..."
binding="..."
bindingConfiguration="..."
behaviorConfiguration="LegacyServiceEndpointBehavior"
contract="..."
name="..." />
</client>
And we are all set to go.
Original Post: WCF: Building an HTTP User Agent Message Inspector
The content of the postings is owned by the respective author. CSharpFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on CSharpFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.