Introduction
During all these years of interaction with several BizTalk developers, I have noticed that very few have the knowledge of BizTalk Multipart messages and how to correctly use them. In this article, I shall attempt to explain how and when to use Multipart Messages in BizTalk.
Environment
The concepts and code in this article apply to BizTalk Server 2006/2006 R2/2009/2010.
What is a BizTalk Multipart Message?
In BizTalk Server, a multipart message is one which has one or more parts, where each part can be either a XML Schema Definition (XSD) schemas or a .NET class.
When a multipart message is created in BizTalk, the first part would be the body part of the message. This means that the property 'Message Body Part' shall be 'true' for the first part. For all the subsequent parts in a multipart message, the property 'Message Body Part' shall be 'false'. Note that, the order of creation of a multipart message parts is vital, since it avoids compilation errors.
Every BizTalk multipart message must have at most one message body part set to 'true
', in order for it to be valid. In order words, there can be only one part, whose message body part is 'true
'.
What are the Steps Required to Create a BizTalk Multipart Message within an Orchestration?
Step 1: In the Orchestration View window, expand the Types node and right-click 'Multi-part Message Types' and then click New Multi-part Message Type.
Step 2: Select 'MultipartType_1'
and then 'MessagePart_1'
, rename accordingly. Notice that for the part 'MessagePart_1'
, the property 'Message Body Part' shall be 'true'
since it's the first part.
Step 3: Select the 'Type
' property for the part 'MessagePart_1'
and associate it with a type which would be a schema.
What is the Message Type for a BizTalk Multipart Message?
The message type for a BizTalk message is identified with the BTS.MessageType
property. For a multipart message, it would be the message part with the property 'Message Body Part' = 'true'
.
What Happens when a BizTalk Orchestration Receives More Parts in a Multipart Message, Than Was Declared Originally?
If a BizTalk orchestration receives a multipart message which contains additional number of parts than what has been declared, then the orchestration engine maps the proper part types, for the parts that match the number of parts in the declared message type and then constructs XmlDocument
parts for the remaining parts.
What are the Steps to Capture these Additional Parts?
Step 1: Declare two variables 'xLangMessage
' and 'xLangPart'
which are of type Microsoft.XLANGs.BaseTypes.XLANGMessage
and Microsoft.XLANGs.BaseTypes.XLANGPart
respectively. Note that you might have to reference the DLL 'Microsoft.XLANGs.BaseTypes'.
Step 2: Assign the multipart message to the variable 'xLangMessage
', declared in Step 1.
Step 3: Loop through the multipart message to retrieve one part at a time. Don't forget to increment the loop counter.
Loop condition:
count < xLangMessage.Count
Extraction:
xLangPart = xLangMessage[count];
count = count + 1;
Is There a Way to Add Additional BizTalk Multipart Message Parts at Runtime within an Orchestration?
Yes, within an Orchestration, BizTalk Server provides the ability to add parts to a multipart message.
Step 1: Create a variable, name it as 'msgPart
' of type Microsoft.XLANGs.BaseTypes.XLANGMessage
, you would need to reference the DLL 'Microsoft.XLANGs.BaseTypes
'.
Step 2: Place an expression shape and add the following line:
msgPart.AddPart(objectName, partName);
where objectName
would be xmlDocument
instance and partName
is the name of the Multipart message part.
When Do You Want to use a BizTalk Multi-part Message?
Scenario 1: Using a Multi-Part Message Type to wrap the underlying schema.
A BizTalk message is always tied to a schema. Provide a level of indirection by creating a multipart message and then associating the schema as one of its parts. Set the messageType
for the message to this newly created Multipart message.
Note that changing a schema associated with a message, when not using multipart messages will require disconnecting all the Ports, Send, and Receive shapes within the Orchestration Designer, hence using multipart messages will avoid this step.
For more information, visit the link '8 Tips And Tricks For Better BizTalk Programming' in the references section in this article.
Scenario 2: Receiving a SOAP envelope (with a SOAP header and SOAP body) within an Orchestration, building a multipart message and sending it to the MessageBox
. A PO envelope multipart message consumer orchestration consumes this message from the MessageBox
.
The idea is to create a multipart message using the SOAP envelope. The PO envelope multipart message would hold the header and the body as two separate parts.
Have a look at the orchestration below:
Extract the SOAP headers using this line of code below:
soapHeader = POIn(WCF.InboundHeaders);
Creating the PO Envelope multipart message:
POEnv.Header_RoutingInfo = PORoutingInfo;
POEnv.Body_PO = POIn;
Setting the SOAP headers for outbound messages.
xmlDocument = PORoutingInfo;
POOut(WCF.OutboundCustomHeaders) = "<headers>" + xmlDocument.OuterXml + "</headers>";
What is the Argument Around WCF Not Supporting BizTalk Multi-part Messages?
Consider a SOAP request arriving at a receive location in BizTalk server. This SOAP request consists of a SOAP header and a SOAP body. The SOAP header would contain a custom context defined by your application. The SOAP body would typically be the schema that was exposed by the orchestration. This ability of the SOAP adapter to split a SOAP request into a BizTalk Multipart message and then send it to Message Box is very useful feature and saves a lot of development effort.
The WCF adapter on the other hand does NOT really care about SOAP envelopes at all. If you have noticed correctly, the "BizTalk WCF Service Publishing Wizard" does NOT even support the addition of custom headers when you would like to expose an Orchestration as a web service.
There is a way to add custom headers to a WSDL generated by WCF adapter. This is beyond the scope of this article. For additional information, refer to the excellent post by Yossi Dahan in the references section.
Some Common Pitfalls
- Avoid defining an orchestration parameter as
XLANGMessage
or XLANGPart
, use a variable instead. - Avoid naming a BizTalk orchestration variable as a '
body
', it does NOT compile as 'body
' is a reserved word.
Common Compilation Errors While Using Multipart Messages
Error: Multi-part message has body part ‘xxx’, expected body part ‘yyy’.
Why Does This Happen?
When a multipart message is first created in BizTalk Orchestration View, the first part created would automatically become the message body part, which means the part's property 'Message Body Part' shall be 'true
'. Consider the case where you would change this property 'Message Body Part' to 'false
' and associate a different schema to it and then create another message body part, with the property 'Message Body Part' set to true
. Note that BizTalk remembers the order in which the parts which were created, where the first part would always have to be a message body part.
What is the Resolution?
When a BizTalk Multipart message is first created, associate the schema for the message body part first (which forms the MessageType
for the multipart message). If they are created in the wrong order, then delete the multi-part message and recreate it again. Problem solved.
References - Don't Miss These Great Posts