Charles Young

  Home  |   Contact  |   Syndication    |   Login
  193 Posts | 64 Stories | 508 Comments | 373 Trackbacks

News

Twitter












Article Categories

Archives

Post Categories

Image Galleries

Alternative Feeds

BizTalk Bloggers

BizTalk Sites

CEP Bloggers

CMS Bloggers

Fun

Other Bloggers

Rules Bloggers

SharePoint Bloggers

Utilities

WF Bloggers

Introduction

 

The other day, a colleague raised a 'problem' that turned out to be no problem at all.   They wanted to invoke a web service from within an Orchestration.   The web services had been created using .NET, and the WebMethod they wanted to call accepted no parameters:

 

      [WebMethod]

      public Customer getCustomer ()

      {

            ...

            return customer;

      }

 

Having provided their BizTalk project with a reference to the web service, he then tried to work out how to construct an 'empty' message that could be sent to the .asmx file to invoke the WebMethod.   I wasn't standing over my colleague's shoulder, but I would guess that he probably created a message, typed it using the correct Web Message Type, dropped a Message Assignment shape onto the Orchestration (which, of course, would be contained inside a Construct Message shape) and then tried to work out how to initialise the message within the expression code.   Every attempt failed.

 

The answer of course, is very simple.  A Web Message Type is really a Multi-part Message Type, and in this case the type defined a multipart message with no parts!  BizTalk insists that Multi-part messages have at least one part (designated the Body part), but will make an exception for Web Messages.  All that was needed was an empty Construct Message shape configured to construct the message.   This would create the necessary 'empty' message which could then be used to invoke the WebMethod.  It took me a second look before I realised where he was going wrong because, like him, I had got used to writing expressions in Message Assignment shapes to initialize messages.   In this case, however, the message needed only to be constructed.  No initialisation is required.

 

Message initialisation often comes as a surprise to developers new to BizTalk Server 2004.  An understanding of what happens behind the scenes can be useful, and this article explains BizTalk's behaviour in this respect.   In a sense, this subject is the 'ABC' of Orchestration development.   However, some aspects are not very clearly explained within the documentation, and even experienced BizTalk 2004 developers (do any exist yet?) may not understand some of the finer points.

 

Message and Part classes

 

Within an Orchestration, BizTalk Server 2004 uses .NET classes to represent individual messages.    These classes act as generic wrappers around the underlying message data, and are quite straightforward.   Each message class is auto-generated in C# as a derived Microsoft.BizTalk.XLANGs.BTXEngine.BTXMessage type.  This class is not documented, but is derived as follows:

 

      System.Object

            Microsoft.XLANGs.BaseTypes.XLANGMessage

                  Microsoft.XLANGs.Core.XMessage

                        Microsoft.BizTalk.XLANGs.BTXEngine.BTXMessage

 

The base XLANGMessage class is documented, and is the type generally used when passing messages out to your own code.   Each XLANGMessage is a collection of Microsoft.XLANGs.BaseTypes.XLANGPart objects.   Orchestrations use the Microsoft.XLANGs.Core.DotNetPart class derived as follows.

 

      System.Object

            Microsoft.XLANGs.BaseTypes.XLANGPart

                  Microsoft.XLANGs.Core.Part

                        Microsoft.XLANGs.Core.DotNetPart

 

Again, the DotNetPart class in undocumented, while the XLANGPart class is documented and generally used within your own code.

 

The auto-generated message classes not only provide an enumerable collection of parts, but also provide each part as a public field.  Each part has a LoadFrom() method which populates the part object with data.   This method accepts any object as a parameter, but can only populate the part from certain types, such as built-in .NET types, streams, XmlDocuments and XmlElements.

 

When you use a message programmatically within an XLANG/s expression, you are essentially using an abstract representation of a BTXMessage object.  XLANG/s imposes additional constraints over the use of this class and hides details like the LoadFrom() method from the programmer.  There are also some peculiarities with regard to the way parts may or may not be represented in IntelliSense.  We will explore this later.   You can pass messages directly between XLANG/s and external .NET code using method parameters and return values data typed as BTXMessage.

 

Message Construction and Intialisation

 

'Construction' of messages refers to the underlying instantiation of BTXMessage classes that represent messages to the Orchestration engine.   Messages are constructed indirectly using the Construct Message shape (obviously!).  All you need to do to create the instantiation code is to drop a Construct Message shape onto an Orchestration and assign the list of messages you wish to construct to its Messages Constructed property.   This causes the emission of C# code behind the scenes that looks like this:

 

__messagetype_zzTest_test __msgTest = new __messagetype_zzTest_test("msgTest", __ctx1__);

 

__msgTest is the behind-the-scenes variable used to store an instance of the __messagetype_zzTest_test class which is derived from BTXMessage.  Remember always that XLANG/s is merely an abstraction of the generated C# code.  In this case, the XLANG/s message is named 'msgTest'.  The BTXMessage constructor creates Part object instances and assigns these to the public fields.

 

'Initialization' of messages is quite distinct to construction, and refers to the initialization (not the instantiation) of the message part objects.   Until message parts have been fully initialised, the message cannot be used within the Orchestration, and BizTalk will refuse to compile your code.   Of course, if a message has no parts, there is no initialisation to do.

 

Message Typing in XLANG/s

 

Messages can be typed in a variety of ways in XLANG/s.  These types do not affect the underlying .NET types used in the Orchestration code, but do impose higher-level constraints on the content of message parts.  There are three message types: .NET Classes, Schemas and Multi-part Messages.  A fourth type, Web Messages, is really just a Multi-part Message type used in conjunction with SOAP-based web services.

 

Multi-part Messages

 

For Multi-part messages, each individual part is exposed to the developer using IntelliSense.   The parts appear as 'properties' of the message, and you can initialise each part in a straightforward manner depending on the data type selected for that part.   As noted above, Web Message Types are Multi-part Message Types.   The part 'properties' you see in IntelliSense are not true properties, but do map to the underlying public fields of the BTXMessage class.   When you assign a value to a part, C# sharp code is emitted that invokes the LoadFrom() method of the Part object assigned to the corresponding public field:

 

__msgTest.partA.LoadFrom("Hello World");

 

One aspect of multi-part messages which I shall touch on briefly here is that they must have at least one part designated as the 'body' part (this rule is relaxed for web messages which, as mentioned above, can contain no parts).  Within an Orchestration, it is not generally important to know which part is the body part, but this may become a critical issue when the message is passed through a pipeline.   In pipelines, messages are accessed via the IBaseMessage and IBaseMessagePart interfaces.  The IBaseMessage interface defines a 'BodyPart' property, and although other parts can be accessed programmatically, the components and functionality provided by Microsoft generally only use the designated body part for features such as routing and tracking.   The SOAP adapter, which transports web messages, does not depend on the existance of body parts.

 

Schema Messages

 

If you type a message using a Schema, things are very similar.   In this case, the underlying BTXMessage class has a single part field.   It is essentially equivalent to a Multi-part message with a single Part.   However, there are two important differences:

 

  1. IntelliSense does not display the single part.  To initialize the part, you assign a value directly to the message itself in your XLANG/s expression.   This inconsistency between Multi-part and Schema messages is confusing to new BizTalk developers.

  1. The message part is restricted in the data types that can be used to initialise it.   You can use an existing message of the same type, or an instance of either the XmlDocument or XmlElement classes.  Note that you cannot use Stream objects for this purpose within an XLANG/s expression.

.NET Class Messages

 

Messages typed as .NET classes are very similar to Schema messages.  They contain a single part which is not shown in IntelliSense.   In XLANG/s you assign an instance of the required .NET class directly to the message.  .NET classes used in this way must be capable of serialization using the XmlSerializer facilities of the .NET framework.  They may, in addition, be associated with a BizTalk custom formatter for non-XML serialization.  I discussed this to some extent in an earlier post about the SMTP adapter.

 

Property Promotion

 

Further confusion can arise over the issue of promoted properties.   In the XSD schema, you can promote fields which contain singleton values.  There are two types of property promotion; distinguished fields and property fields.

 

  • Distinguished Fields

For Schema message types, distinguished fields are schema 'fields' which are promoted through the use of additional annotation within the XSD schema.   XSD annotations provide an extensibility mechanism that allows additional domain-specific schema semantics to be expressed in a machine-readable fashion. 

 

Messages typed using .NET Class messages also allow distinguished fields.   In this case, fields are the public fields and properties of the class definition.   In order to distinguish a field, you need to define the class yourself in a language such as C#, and add the DistinguishedField attribute to the class fields and properties that you wish to distinguish.

 

Multi-part message types are essentially similar, but with the IntelliSense twist described earlier.  It is important to understand that a message part is not the same as a field.  Consider a Schema message type.  This has a single part that contains an XML document.  Fields are nodes within that XML.   The same approach applies to Multi-part message types.   A single part may be typed as either a .NET class or as a schema.  That class or schema may define distinguished fields.  The twist is the way this is represented in XLANG/s IntelliSense.  IntelliSense works differently for Multi-part messages than for other message types.  In a Multi-part message, each part is displayed as a 'property' of the message.   If the schema or class for that part defines distinguished fields, these are then shown in IntelliSense when you type the dot separator after the part name.   Hence you might have XLANG/s code similar to the following:

 

          msgMultiPart.PartA.ADistinguishedField = "Hello world";

 

Behind the scenes, BizTalk would generate the following C# code:

 

          __msgMultiPart.PartA.SetDistinguishedField("ADistinguishedField", "Hello world");

 

As we have seen, in other message types the single message part is never displayed in IntelliSense.   Distinguished fields are shown as 'properties' directly of the message itself, although they are really associated with the single message part.   To initialise a multi-part message within an Assign Message shape, simply assign values to each of the parts.   For Schema message types you must assign an XmlDocument or XmlElement directly to the message, and for .NET Class messages, you must assign an object instance to the message.   Once the part has been initialised, you can then go on to initialise individual distinguished fields if you so wish.

 

  • Property Fields

Every message that flows through BizTalk has contextual data associated with it.  This contextual data includes message properties.   Properties are defined and stored externally to the message, but are associated with the message at runtime.  Note the subtle, but important difference between distinguished fields and property fields.   A distinguished field is a specially identified field within a message part, while a property field is contextual data associated with the message itself, rather than an individual message part.  It is simply a rather confusing peculiarity of IntelliSense that distinguished fields appear to be message-level properties for Schema and .NET Class messages.

 

You use Schemas and .NET Classes to define the layout of message parts (just like WSDL), rather than messages.  Hence, for contextual Property Fields, BizTalk cannot place the definitions of these properties within individual schemas or classes.   Instead, you must create an additional Property Schema.   You can then promote individual fields within a part by mapping the field definition in the schema or class to the property definition in the Property Schema.   At run-time, the promoted data within individual message parts becomes accessible at the message level.

 

XLANG/s provides a special syntax for accessing message properties.  You use a programmatic identifier within parenthesis immediately after the message name.  Hence you might have code that looks like this:

 

          msgMultiPart(APropertyField) = "Hello world";

 

The 'APropertyField' message property might be mapped to a single node inside the XML contained in on the message parts.

 

If you want to promote a field within a .NET class as a property field, use the Property attribute within your class definition in front of your public property or field definition.

 

Conclusion

 

The subject of this article is one of the most basic subjects within BizTalk Orchestration development.   However, some of the finer points are not well explained within the documentation.   A detailed knowledge of how messages, message parts and promoted fields are handled within BizTalk Server 2004 is indispensable to BizTalk developers.

posted on Wednesday, May 5, 2004 4:48 PM

Feedback

# How messages work in BizTalk Server 2004 Orchestrations 5/5/2004 11:55 AM Charles Young
The finer points of message handling in Biztalk Server 2004 are not always well understood. This article attempts to shed some light on how messages are handled with Orchestrations, and the more confusing aspects of message initialisation.

# re: How messages work in BizTalk Server 2004 Orchestrations 6/24/2004 7:03 PM Sachin
Very good Info. BTS documentation should take a cue!!

# re: How messages work in BizTalk Server 2004 Orchestrations 8/24/2004 8:49 AM Alex
This article is very interresting.
I want call a web service method in an orchestration and the response is an object look like this :

public class MessageResponse
{
private MessageError error;
public MessageError Error
{
get
{return error;}
set
{error = value;}
}
private InsertDocumentBody body;
public InsertDocumentBody Body
{
get
{return body;}
set
{body = value;}
}
}
I would see this object in an orchestration with IntelliSense.
it's possible?

The message response object must be derived from Microsoft.XLANGs.BaseTypes.XLANGMessage.

Thx in advance,
Ale

# re: How messages work in BizTalk Server 2004 Orchestrations 11/10/2004 2:04 AM Paul
I read this and read it again but am no clearer on how your colleague solved their problem in the introduction. ie. how to create a empty typed message.
Shame as I have the same issue

# re: How messages work in BizTalk Server 2004 Orchestrations 1/7/2005 9:00 AM Pal AB
This article helped me a lot to understand the message behavior. Definitely are right. To call a web method with no parameters, only the construction of message is required. No initialization is required for this. In construct message shape, include the message, which is of type request for the web method having no parameters. Not required to initialize any value.

# re: How messages work in BizTalk Server 2004 Orchestrations 2/18/2005 4:27 PM Oddur Magnusson
I'm trying to create a web request message which I will then configure using xpath in a expression share right after the construction of the web message, with no luck . The Web message has one part, which is called UpdateRequest, it's value is something I already have, but can only access through a xpath.

If I try to do in the assign message shape :
xpath(webRequest.UpdateRequest, "//foo") = xpath(prevmsg.response, "//bar");
I get a error saying :
"message part has not been initialized in construct statement"

If I could somehow initialize it an then do the xpath = xpath in a expression shape after the construct, that migth solve my headache.

Any ideas ?

# Создание сообщений. 7/20/2005 12:58 AM ares-unlimited Blog
??????? ??????????????? ? ????????????? ????????? ? Biztalk 2004

# Biztalk Server 2004 & 2006: Useful Links & Tips 9/20/2005 2:43 PM Lito Damiani
Hi everyone! This post is aimed for those developers who are giving their first steps with Biztalk...

# re: How messages work in BizTalk Server 2004 Orchestrations 9/23/2005 8:39 AM Gary
An empty construct shape results in:

"message has not been initialized in construct statement"

Any ideas?

# re: How messages work in BizTalk Server 2004 Orchestrations 4/14/2006 9:26 AM Maurício Ritter
Hi Charles,

Great post ! I just have one quick question:
1) Let's assume that you have an orchestration with a multi-part message that have 3 parts. Each one of this parts represents a schema that are in your assembly as well. This schemas have promoted PROPERTYS. Let's say that in this orchestration I'm using a direct binding port to send the message to another orchestration, but I'll send the multi-part message instead of an individual message. My question: In the other orchestration I want to use a Receive Port with direct binding and base my filters on propertys of different parts of the multi-part message. This will work ? I got it working here in one solution, but couldn't get it working on another one (maybe I'm doing something wrong). Just want to know your thought about it.

Maurício Ritter

# Web Message with mixed types don't seem to work 3/5/2008 11:35 AM Robert
Hello all,

I have a wsdl with, among several services declared, declare a Logon and a Logoff Services

The differecce between them is that
Logon has
- 4 simple types
- 1 complex type, session

Logoff has
- 1 complex type, session

This is the status
- I can handle the construction and inicialization of Logoff request messages

- For the construction of the Logon request message
- i can instanciate the message
- have the all 5 message parts available
- can inicialise the 4 simple types message parts
- serialization of the complex type fails in the call

Am I doing anything wrong ? ....

Thanks in advance



<s:element name="Login">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="a_UserName" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="a_Password" nillable="true" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="a_UserSession" nillable="true" type="tns:session" />
<s:element minOccurs="1" maxOccurs="1" name="a_IsAuthorized" type="s:boolean" />
<s:element minOccurs="1" maxOccurs="1" name="a_Result" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="session">
...
</s:complexType>
<s:element name="Logoff">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="a_UserSession" nillable="true" type="tns:session" />
</s:sequence>
</s:complexType>
</s:element>

# re: How messages work in BizTalk Server 2004 Orchestrations 3/5/2008 11:54 AM Robert (2)
Basically, I am having problems calling a web method like
MyClass1 MyMethod( string a, string b, MyClass2 obj2 )

but have no problems calling web methods like
MyClass1 MyMethod( MyClass2 obj2 )
or
MyClass1 MyMethod( string a, string b )



# re: How messages work in BizTalk Server 2004 Orchestrations 3/7/2008 3:54 PM Robert (3)
I implemented a solution for this problem
1. create a message of the same type of the message part
2. assing it to the message part. As Youg said, you will be assigning the message stream wich is what is pretended (msg initialization).

BTW the web service i'm calling has in/out arguments, wich I assume that will be returned in a multi-part message - each message part por each argument

# Web Message with mixed types don't seem to work 3/12/2008 8:22 AM Robert (last)
Found de cause: a mok service I used to emulate the backend generated a response that was not compliant with soap biztalk expeted.

I created a dummy WS and everthing worked fine



# re: How messages work in BizTalk Server 2004 Orchestrations 4/30/2008 4:04 AM Grd
Hi Robert,
Could you please post this article somewhere.

Thanks,
Grd

# re: How messages work in BizTalk Server 2004 Orchestrations 7/14/2008 12:31 AM avatarlar
This&nbsp;post is aimed for those developers who are giving their first steps with Biztalk...

# re: How messages work in BizTalk Server 2004 Orchestrations 7/17/2008 8:46 PM avatarlar
Basically, I am having problems calling a web method like
MyClass1 MyMethod( string a, string b, MyClass2 obj2 )

but have no problems calling web methods like
MyClass1 MyMethod( MyClass2 obj2 )
Msn

# re: How messages work in BizTalk Server 2004 Orchestrations 4/16/2009 12:53 PM bone cancer symptoms
This article helped me a lot to understand the message behavior. Definitely are right. To call a web method with no parameters, only the construction of message is required. No initialization is required for this. In construct message shape, include the message, which is of type request for the web method having no parameters. Not required to initialize any value.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: