The WCF framework exposes the so-called extension points through which it is possible to implement additional functionalities in the WCF pipeline. One such extension point is MessageInspector
object that can be used to change messages after they have been received at the service endpoint or before they are sent from it. BizTalk offers registration of WCF extension points in WCF-Custom adapter.
WCF Message Inspectors
IMessageInspector
consists of two interfaces:
IClientMessageInspector
interface exposes methods for modifying a message before sending a message or receiving a response from the client sideIDispatchMessageInspector
interface exposes methods for modifying a message after receiving it on the server side or before sending a it as a response
The following code snippet shows MessageInspector
interfaces.
public interface IClientMessageInspector
{
object BeforeSendRequest(ref Message request, IClientChannel channel);
void AfterReceiveReply(ref Message reply, object correlationState);
}
public interface IDispatchMessageInspector
{
object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext);
void BeforeSendReply(ref Message reply, object correlationState);
}
It is important to note that the message is transmitted to the IMessageInspector
interfaces as a reference to the object of type Message
, which ensures that changes to the message object are propagated to the caller. The body of message can be read only once, so if implementation details require multiple writing or reading of messages, it is neccessary to call the CreateBufferedCopy
method that saves the entire message in the memory buffer which can then be manipulated as needed. The return value of the BeforeSendRequest
and AfterReceiveReply
methods can be any arbitrary object and it will later be used as corellation parameter in BeforeSendReply
and AfterReceiveReply
methods. If no correlation is required, it is sufficient to return null
value.
Fetching BizTalk message context properties in WCF inspector
BizTalk context properties have name, namespace and value. it is possible to fetch these properties in WCF MessageInspector
from Properties
collection on Message
object. Each message property in this collection is saved as key-value pair, where key is formed as namespace#name
.
The following code snippet shows ReceivedFileName
property retrieval from the context of the message.
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var propNS = "http://schemas.microsoft.com/BizTalk/2003/file-properties";
var propName = "ReceivedFileName";
string key = propNS + "#" + propName;
object propValue = null;
if (request.Properties.TryGetValue(key, out propValue))
{
// property is stored in propValue variable
// do something with fetched value...
}
}
Copying properties from WCF message to the context of BizTalk message
Properties that are written to the context of BizTalk messages are key-value pairs, namely the collection of KeyValuePair<XmlQualifiedName, object>
objects whose key is the full name of the property, formed as namespace:name
, and the value is exactly the value of the property to be written.
Properties are written in the context of a BizTalk message by adding this collection of the KeyValuePair
objects in the Properties
collection of Message
object with key http://schemas.microsoft.com/BizTalk/2003/file-properties
.
Similarly, promoting properties in the context of the BizTalk message is done by adding the properties in the same format, in the same Properties
collection, but with the key http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties/Promote
.
The following code snippet shows how custom WCF property can be written and promoted to context of BizTalk message as ReceivedFileName
property.
public void AfterReceiveReply(ref Message reply, object correlationState)
{
// List and namespace for writing properties
var writePropertiesList = new List<KeyValuePair<XmlQualifiedName, object>>();
var writePropertiesNS = "http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties/WriteToContext";
// List and namespace for promoting properties
var promotePropertiesList = new List<KeyValuePair<XmlQualifiedName, object>>();
var promotePropertiesNS = "http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties/Promote";
// Property to write and promote
var propNS = "http://schemas.microsoft.com/BizTalk/2003/file-properties";
var propName = "RecivedFileName";
var propValue = "YourCustomFileName.xml";
var property = new KeyValuePair<XmlQualifiedName, object>(new XmlQualifiedName(propName, propNS), propValue);
// write
writePropertiesList.Add(property);
if (reply.Properties.ContainsKey(writePropertiesNS))
reply.Properties[writePropertiesNS] = writePropertiesList;
else
reply.Properties.Add(writePropertiesNS, writePropertiesList);
// promote
promotePropertiesList.Add(property);
if (reply.Properties.ContainsKey(promotePropertiesNS))
reply.Properties[promotePropertiesNS] = promotePropertiesList;
else
reply.Properties.Add(promotePropertiesNS, promotePropertiesList);
}