Can I add Custom SOAP header in WCF incoming/outgoing messages in basicHttpBinding, like we can add custom authentication header in ASMX web services? Those custom SOAP header should be accessible using .net 2.0/1.1 web service clients (accessible by WSDL.EXE tool) .
Wcf – How to add custom soap headers in wcf
wcfwcf-client
Related Solutions
The advantage to this is that it is applied to every call.
Create a class that implements IClientMessageInspector. In the BeforeSendRequest method, add your custom header to the outgoing message. It might look something like this:
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();
httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, this.m_userAgent);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
Then create an endpoint behavior that applies the message inspector to the client runtime. You can apply the behavior via an attribute or via configuration using a behavior extension element.
Here is a great example of how to add an HTTP user-agent header to all request messages. I am using this in a few of my clients. You can also do the same on the service side by implementing the IDispatchMessageInspector.
Is this what you had in mind?
Update: I found this list of WCF features that are supported by the compact framework. I believe message inspectors classified as 'Channel Extensibility' which, according to this post, are supported by the compact framework.
Ok, so there's two main things that need to occur:
- Get the cookie from the web app context to the WCF service
- Get the cookie from the WCF service to the ASMX service
NOTE: Because you didn't specify, I'm going to assume that you're using a WCF client within your WCF service to talk to the ASMX service. If this is not the case please let me know and I will revise this post accordingly.
Step #1:
I would recommend writing an IClientMessageInspector which you bind to your client endpoints using an IEndpointBehavior. In your implementation of IClientMessageInspector::BeforeSendRequest you basically read the cookie out of the current HttpContext::Request::Cookies collection and append the value as a message header. That would look a little something like this:
public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Get the cookie from ASP.NET
string cookieValue = HttpContext.Current.Request.Cookies["MyCookieName"].Value;
// Create a header that represents the cookie
MessageHeader myCookieNameHeader = MessageHeader.CreateHeader("MyCookieHeaderName", "urn:my-custom-namespace", cookieValue);
// Add the header to the message
request.Headers.Add(myCookieNameHeader);
}
One you configure the endpoint with this message inspector every logical request will automatically flow the cookie value through as a header to your WCF service. Now, since your WCF service doesn't actually care about the header itself, it can basically ignore it. In fact, if you only did this step, you should be able to run all your code right now and not experience any difference.
Step #2:
Now we need the cookie to go from the WCF service to the ASMX service. Once again all you need to do is implement an IClientMessageInspector, except your BeforeSendMessageRequest is going to be a little different:
public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Get the cookie value from the custom header we sent in from step #1
string cookieValue = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("MyCookieHeaderName", "urn:my-custom-namespace");
HttpRequestMessageHeaderProeperty httpRequestMessageHeaderProperty;
MessageProperties outgoingMessageProperties = OperationContext.Current.OutgoingMessageProperties;
// Get the HttpRequestMessageHeaderProperty, if it doesn't already exist we create it now
if(!outgoingMessageProperties.TryGetValue(HttpRequestMessageHeaderProperty.Name, out httpRequestMessageHeaderProperty))
{
httpRequestmessageHeaderProperty = new HttpRequestMessageHeaderProperty();
outgoingMessageProperties.Add(HttpRequestMessageHeaderProperty.Name, httpRequestmessageHeaderProperty);
}
// Set the cookie header to our cookie value (note: sample assumes no other cookies set)
httpRequestmessageHeaderProperty.Headers[HttpRequestHeader.Cookie] = cookieValue;
}
Once again you need to bind this to the endpoint for your ASMX service using an IEndpointBehavior and every logical request you make will automatically pass the cookie through.
Best Answer
Check out the WCF Extras on Codeplex - it's an easy extension library for WCF which offers - among other things - custom SOAP headers.
Another option is to use WCF message contracts in your WCF service - this also easily allows you to define and set WCF SOAP headers.
Here, the "operation" and the "transactionDate" are defined as SOAP headers.
If none of those methods help, then you should check out the concept of WCF Message Inspectors which you can write as extensions. They allow you to e.g. inject certain headers into the message on every outgoing call on the client, and retrieving those from the message on the server for your use.
See this blog post Handling custom SOAP headers via WCF Behaviors for a starting point on how to write a message inspector, and how to include it in your project setup.
The client side
IClientMessageInspector
defines two methodsBeforeSendRequest
andAfterReceiveReply
while the server sideIDispatchMessageInspector
has the opposite methods, i.e.AfterReceiveRequest
andBeforeSendReply
.With this, you could add headers to every message going across the wire (or selectively only to a few).
Here's a snippet from a
IClientMessageInspector
implementor we use to automagically transmit the locale information (language and culture info) across from the clients to the server - should give you an idea how to get started:On the server side, you'd then check for the presence of those headers, and if present, extract them from the SOAP envelope and use them.
UPDATE: okay, you're clients are on .NET 2.0 and not using WCF - good news is, this should still work just fine - see this blog post Custom SOAP Headers: WCF and ASMX for details. You could still use the message inspector on the server side to sniff and extract the custom headers being sent by your .NET 2.0 clients.