For those who extend their BizTalk solutions using WCF behaviors, a common challenge is working out how to flow details from your BizTalk message into your WCF behavior extension so that you can access them in the extension.
Luckily for you, BizTalk and WCF are like a match made in heaven and work together really seamlessly. BizTalk context properties flow through to WCF behavior extensions and are easily accessible, and it is quite possible to flow details back from a WCF behavior to the response message’s BizTalk context as well.
For the rest of this blog post I will assume that you have already setup a WCF Message Inspector extension and are making use of it on a WCF send port in BizTalk (a lot of what I demonstrate should be applicable for other types of behavior extensions and for receive locations as well). I will demonstrate how you can access BizTalk context from within your Message Inspector, and also how you can set context property values on the response message as well.
For your request messages this is a no brainer. Every single context property that was attached to the message in BizTalk will automatically flow through to your WCF Message Inspector in the form of a property bag attached to the request message. Context property values can be fetched out of the property bag by using the context property namespace#name as in the following example which fetches the BTS.Operation context property value (you would normally of course want to check whether you are getting a null value back before converting it to a string to avoid a NullReferenceException in case the context property didn’t exist in the property bag).
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
string _BTSOperation = request.Properties["http://schemas.microsoft.com/BizTalk/2003/system-properties#Operation"].ToString();
///Do some stuff with the BTS Operation
Leveraging your context properties in WCF behaviors opens the door towards much more cohesive solutions in which you use the right types of components for the right kinds of problems. A good example of this would be scenarios in which you need to calculate an OAUTH signature, which is probably best done in a WCF behavior, however you might have otherwise been tempted to do it in a pipeline component instead since you needed access to BizTalk context properties. Knowing that you can flow your context properties through to your behavior extensions keeps your options open.
How about the flip side when you want to flow some data back from your WCF behavior to BizTalk context properties. Here your options diverge slightly depending on whether you are dealing with a SOAP or RESTFul service based on the WCF-WebHttpBinding binding, and you’ll also find that all options include a bit more difficulty. You can choose to pass the context in the form of inbound SOAP headers or inbound HTTP headers as demonstrated in the following code snippet.
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
//Writing to WCF.InboundHttpHeaders context property
System.ServiceModel.Channels.HttpResponseMessageProperty httpHeaders = (System.ServiceModel.Channels.HttpResponseMessageProperty)reply.Properties["httpResponse"];
httpHeaders.Headers.Add("ContextHTTPHeader", "Content property value");
//Writing to WCF.InboundHeaders as well as to http://contextproperty#ContextSOAPHeader context property
var header = new MessageHeader<string>("Content property value");
var untypedMessageHeader = header.GetUntypedHeader("ContextSOAPHeader", "http://contextproperty");
So if I actually use this behavior on a WCF SOAP based send port what will the result look like?
We can see that populating an inbound HTTP header in the WCF behavior has resulted in an HTTP header called ContextHTTPHeader being appended to the end of the WCF.InboundHttpHeaders context property. You can use the BRE Pipeline Framework to extract individual HTTP headers easily. The value of the context property looks like the below.
X-XSS-Protection: 1; mode=block
Cache-Control: private, max-age=0
Content-Type: application/soap+xml; charset=utf-8
Date: Wed, 01 Jul 2015 08:59:10 GMT
Server: WWW Server/1.1
ContextHTTPHeader: Content property value
Populating the inbound SOAP header in the WCF behavior actually results in it showing up in two context properties. The first is in the WCF.InboundHeaders context property, and the value looks like the below.
The second context property which you’ll notice is a custom context property with the same name/namespace as the SOAP header which we created – http://contextproperty#ContextSOAPHeader.
In both of the above scenarios you’ll notice that it isn’t too simple to actually extract the value that you set for your inbound SOAP header. Once again, the BRE Pipeline Framework could help you extract the value using regex.
Note that if you try to set an inbound SOAP header in a WCF behavior on a WCF-WebHttp send port you will be met with the following exception.