For a recent project I needed to send messages to BizTalk through an ASP.NET application.
The purpose of the ASP.NET website was to provide a simple user interface to send messages to BizTalk, where people can download / upload messages (with validation).
The users can first validate their message, this is done through a BizTalk pipeline that parses the message and does several checks to see if it is valid.
I exposed a request-response receive location using net named pipe binding that executes the validation.
The BizTalk pipelines parses the message and converts it to a “Validator Message” that contains the errors / warnings of the message.
Some of the files that are uploaded are pretty huge ( > 100 mb as a flatfile).
That is one of the reasons why I opted for the net.pipe binding, because this binding can implement streaming (note: not all bindings can implement streaming mode!).
Another reason why I opted for that binding is because this binding is perfect for communication between WCF applications on the same machine.
BizTalk
Here is how I set-up the BizTalk side.
I created one request-response receive port and added a receive location. I route the message I receive from the receive pipeline directly back to the send pipeline of that port, so I don’t need additional send ports.
You can see how to do this in another blogpost.
The receive location uses the WCF-Custom adapter with the netnamedBinding.
I changed some default values, like the maxReceivedMessageSize, and made sure that “transferMode” is set to “Streamed”.

I also needed to change some settings in the “Messages” section.
I had to change the inbound and outbound message body, this is dependent on how you name the WCF interface in your .NET application (see section “.NET application” below).
Inbound Message Body
Extract the stream by selecting the xpath, in my case the xpath looks like following:
/*[local-name()='SubmitMessage' and namespace-uri()='http://App.services/BizTalk']/*[local-name()='Message' and namespace-uri()='http://App.services/BizTalk']
Also make sure that you set the Node Encoding to “Base64”, since we are sending a stream.
Outbound Message body
You also need the “wrap” the stream we receive back, so it is a valid response message according the interface of the WCF service we setup in the .NET application.
You can do this by setting the template. In my case I had to set it like following:
<ns0:SubmitMessageResponse xmlns:ns0="http://App.services/BizTalk">
<ns0:SubmitMessageResult xmlns:ns0="http://App.services/BizTalk">
<bts-msg-body xmlns="http://www.microsoft.com/schemas/bts2007" encoding="base64"/>
</ns0:SubmitMessageResult>
</ns0:SubmitMessageResponse>
Be sure to include the “encoding” parameter so it encodes the message as base64.

Only thing left to do is set the uri of the receive location, example: net.pipe://localhost/App/ValidatePricat
.NET Application
First thing to do is create the WCF interface.
I implemented the “IClientChannel” so I could use an OperationContextScope in my client to add a custom WCF header.
[ServiceContract(Namespace = "http://App.services/BizTalk")]
public interface IBizTalkSubmitService : IClientChannel {
[OperationContract(Action = "*", ReplyAction = "*")]
Stream SubmitMessage(Stream Message);
}
Now for sending the stream to BizTalk.
FIrst create a channelfactory of the interface above, using the correct binding.
Make sure you set the transferMode to “Streamed”.
NetNamedPipeBinding b = new NetNamedPipeBinding("NetNamedPipeBinding_BizTalkService");
EndpointAddress epa = new EndpointAddress("net.pipe://localhost/App/" + operation);
var myChannelFactory = new ChannelFactory<IBizTalkSubmitService>(b, epa);
Next create the client. You will see I am using an OperationContextScope. This is for adding a custom WCF header.
The reason why I need to add a custom WCF header is because the site is multilingual, so I implemented multiple languages in the BizTalk solution for returning error / warning messages concerning the validity of the message in the correct language.
You will see following line of code:
header.GetUntypedHeader("PropertyContainer", "https://R4A.Properties");
BizTalk will automatically promote the messageheader in the context. For this to work, you will need to create (and deploy) a propertyschema containing the property “PropertyContainer” (the one you defined in the above line of code) in the correct namespace.
The value of the “propertycontainer” is an XML document that has been encoded (but this could also be a simple string), I did this because I have multiple properties (language, some codes for validation, ..) and this way I can easily extract it in a custom pipelinecomponent in BizTalk.
This is the full code:
public Stream SendMessage(string operation, Dictionary<string, string> contextProperties, Stream message)
{
NetNamedPipeBinding b = new NetNamedPipeBinding("NetNamedPipeBinding_BizTalkService");
EndpointAddress epa = new EndpointAddress("net.pipe://localhost/App/" + operation);
var myChannelFactory = new ChannelFactory<IBizTalkSubmitService>(b, epa);
IBizTalkSubmitService client = null;
Stream response = null;
try
{
client = myChannelFactory.CreateChannel();
using (OperationContextScope contextScope = new OperationContextScope(client))
{
if (contextProperties != null)
{
XmlDocument xDoc = new XmlDocument();
XmlElement rootNode = xDoc.CreateElement("PropertyContainer");
foreach (KeyValuePair<string, string> pair in contextProperties)
{
XmlElement prop = xDoc.CreateElement(pair.Key, "https://R4A.Properties");
prop.InnerText = pair.Value;
rootNode.AppendChild(prop);
}
xDoc.AppendChild(rootNode);
var header = new MessageHeader<string>(HttpUtility.HtmlEncode(xDoc.InnerXml));
var untyped = header.GetUntypedHeader("PropertyContainer", "https://R4A.Properties");
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
}
response = client.SubmitMessage(message);
}
((IClientChannel)client).Close();
}catch(Exception ex)
{
((IClientChannel)client).Abort();
}
return response;
}
That’s it!
Now simply call the “SendMessage” method and you can send a stream to BizTalk and receive a stream back.
This way my website doesn’t need to read the message and no memory problems can be encountered, because everything works streaming.
And using the custom WCF header, I can still add some extra information to the message.
I couldn’t find a similar blogpost about this subject, so hopefully this will help you :)
3e2555f4-219c-45bd-a066-2c826d04597e|5|4.2