I was having issues with BizTalk’s promoted/distinguished fields today, so I ran a small test, and I’m not sure what I have here.
What I want to see is when I change various values in a message (e.g. promoted property fields, distinguished fields, the message directly), when do the other values (e.g. promoted property fields, distinguished fields, the message directly) get updated? For instance, when I set a promoted value for a message, when does it get “pushed down”?
I have a very simple BizTalk project with a schema, property schema, and orchestration. In the schema I have a field called Node1 and I have both distinguished and promoted that field (into a property field named RoutingNode). In my orchestration, I have a series of activities where I manipulate the message in all sorts of sinister ways. Construct Block #1 has the following code contained (I’ve subtracted most of my trace statements):
SampleSchema_Output1 = SampleSchema_Input;
//print out distinguished value, promoted value, and actual XML content
System.Diagnostics.Debug.WriteLine(“Distinguished: ” + SampleSchema_Output1.Node1 + “; Promoted: ” +
SampleSchema_Output1(BizTalk.Blog.MonitorMessageChanges.RoutingNode));
xmlDoc = SampleSchema_Output1;
System.Diagnostics.Debug.WriteLine(“XML content: ” + xmlDoc.OuterXml);
//change promoted value
SampleSchema_Output1(BizTalk.Blog.MonitorMessageChanges.RoutingNode) = “changed #1”;
//print out distinguished value, promoted value, and actual XML content
System.Diagnostics.Debug.WriteLine(“Distinguished: ” + SampleSchema_Output1.Node1 + “; Promoted: ” +
SampleSchema_Output1(BizTalk.Blog.MonitorMessageChanges.RoutingNode));
System.Diagnostics.Debug.WriteLine(“XML content: ” + xmlDoc.OuterXml);
Got that? So I print out the current values stored in the distinguished field, promoted property field and then the whole message itself. Then I change the promoted property value, and print the whole thing out again. In Construct Block #2 I have the following code (all trace statements removed since you get the point):
SampleSchema_Output2.Node1 = “changed #2”;
So in that one I changed the distinguished field value. Finally, in Construct Block #3 I changed the underlying XML document itself:
//change xml directly
xmlNode = xmlDoc.DocumentElement.SelectSingleNode(“/*[local-name()=’SampleSchema’ and
namespace-uri()=’http://BizTalk.Blog.MonitorMessageChanges’%5D/*%5Blocal-name()=’Node1′ and namespace-uri()=”]”);
xmlNode.InnerText = “changed #3”;
So if you’re still with me, you may be interested in the results of this little experiment. What do you expect to be printed out after each Construct block? Here’s what I got:
I don’t think I expected that. From that experiment, it looks like the XLANG message either updates itself automatically, or, when I request the values (like distinguished fields or promoted properties) it’s checking for changes. Did I do something off here, or does this seem right to you people?
Technorati Tags: BizTalk
Hello Richard,
I’m not too surprised from the outcome. Following snippet is from a MSDN article
“A very important concept to understand is that all messages are immutable in BizTalk Server 2006. This means that after a message is constructed, it cannot be changed. A message is considered constructed after it is placed into the MessageBox database. Any changes to the message require that a new message is created and used from that point forward. This is especially clear in the Orchestration Designer, where compilation rules force you to follow strict guidelines about constructing a message before using it, and do not allow the message to be altered outside of its construction block. If you need to change the message, you must create a new construction block that creates a message of the same type, copy the original message to the new message, and then make any changes to the new message before leaving the construction block.”
I’ve blogged about this behaviour quite sometime back at
http://www.digitaldeposit.net/blog/2006/08/why-messages-are-immutable-inside.html
So, what’s happening in your test?
From your post I can see, inside your Construct block, the very first step you were doing is message assignment
SampleSchema_Output1 = SampleSchema_Input;
SampleSchema_Output2 = SampleSchema_Output1;
SampleSchema_Output3 = SampleSchema_Output2;
This statements will trigger biztalk to create new messages (because of the immutable behaviour of messages inside biztalk). Then whatever changes you make obviously gets reflected on the new messages automatically. That’s the reason why you can only alter the messages inside the construct shape. If you place the same statement inside an expression shape, but outside “Construct” shape, Orchestration designer will throw compilation errors.
Nandri,
Saravana
Thanks for the comment. I guess my initial thoughts were that things would get synched AFTER the construct block was done, not while I was still monkeying with the message within the Assignment shape. BTW, love your new site.
Hi Rich,
I find your blog extremely educative and useful for my BizTalk explorations. Thanks a lot for keeping it updated π
I was wondering if you have any plans to migrate the articles here to your new wordpress blog ? Or are you bound by some NDA with microsoft to not migrate them over ?
-Shiva
http://theshiva.us/
Oops. I meant migrating the articles from http://blogs.msdn.com/richardbpi/contact.aspx to the wordpress (this) blog. I tried to contact you from there, and the contact page did nothing….
-Shiva
Hi Shiva, thanks for the note. I thought I updated the “contact” on the old site to come to me.
Microsoft very kindly left the site up, so at the moment, no need to migrate anything over. If they ever disappear, however, you may see them show up here π
Did you ever get a definitive answer on this? My guess is that at the point you’re mucking around in the construct shape it’s still just hanging around in an XmlDocument object and thus the promoted and distinguished properties are merely xpath references into your in-memory XmlDocument; at the point the construct shape exits, all your promoted and distinguished fields get committed to the context and become immutable.
You know, I didn’t. Your theory may be correct.
Hi Richard,
This behavior is strange. Do you still have this sample project around? as new xlang dev I might be able to help you out.
Regards,
Anil
Hey Anil,
I don’t, but hopefully it’s very reproduce-able based on the post.
For construction of messages from source message, Xlang implements something similar to copy-on-write. All the message copies refer to same underlying data stream as long as they all are reading. As soon as one copy tries to change something in the message, it gets its own datastream and no longer shares the stream with other messages. In the example above, if you dump all the messages rather than just the one on which the construct block is working,you will see the difference. the newly created datastream would be saved/persisted at next persistence point.
Messages become immutable after code inside construct block is finished executing. Also just assigning the promoted property a value is not enough to promote a property. property just get written. see http://blogs.digitaldeposit.net/saravana/post/2007/01/08/Property-Promotion-inside-Orchestration.aspx
Hello sir,
I wish to give my thought on the question raised in this blog (https://seroter.wordpress.com/2007/02/15/synchronizing-biztalk-message-changes/), though after a looong time π what I feel is that the reason the context properties and the data in the message are kept in sync is probably because of the fact that when you promote a property, lets say field element ‘Name’ from the message body whose initial value is “richard”. then you have a send port that subscribes to this message with filter condition “Name = Richard”. now after promoting ‘Name’ into context you modify ‘Name’ field element value in data using xpath as xpath(msgout,”//root/Name”) = “seroter” then what you expect is that this message should not be picked up by the send port as that port should be actually looking for “richard” messages. but in case if the data and the context do not sync up(as per your intensions in the blog ‘neither should change while the other changes’) then this message would land up in the send port, which would not what we expect(as name got changed). Hence keeping context and message data both in sync could be a feature that is probably intended to work in this way.
Thanks
V.Balachandra
http://balachandrav.wordpress.com
http://blogs.msdn.com/balachandra