Friday, 16 October 2009

Hi all

It is pretty common that developers want to assign one message to another inside and orchestration. And as we all know, this must happen inside a “Construct Message” shape.

Inside the “Construct Message” shape, you can have several shapes, but they must all be either a “Transform” shape or a “Message Assignment” shape. The “Transform” shape is used to execute a map, that will generate the message(s) that is/are to be constructed. The “Message Assignment” shape on the other hand uses the expression editor to let you specify how to assign a value to the message(s) that is/are to be constructed.

Often, there is a need to basically copy a message and then change just a couple of values in the copied message. This can’t be done by changing the values of the existing message, as messages in an orchestration are immutable.

Creating the copy is pretty simple; You just assign one message to another like this:

   1: OutputMessage = InputMessage;

Now, what many people realize after doing this and something does not work, like routing, correlation or other is, that this assignment only copies the content of InputMessage to OutputMessage. The context is not copied at all. So what you can do is to add another line of code to your “Message Assignment” shape like this:

   1: OutputMessage = InputMessage;
   2: OutputMessage(*) = InputMessage(*);

This will copy the context of a message from one message to another… but not the entire context, as it turns out.

I was trying out a demo for property demotion, and for this I let my orchestration receive an input message, transform it to an output message and send this out.

So what I did was that I created two schemas:

inputschema and outputschema

I let Field1 and Field3 be promoted into the same promoted property from a custom property schema, and I let Field2 and Field 4 be promoted into another property in a custom property schema.

and a map that does not map anything – it just created empty fields for Field3 and Field4.

In my “Construct Message” shape, I then added a “Transform” shape to do the transformation and a “Message Assignment” shape that would copy the properties. I then wanted to make sure the output of the send port had the demoted values inside it.

What I expected to happen was this:

  1. The XMLReceive pipeline would receive the input, promote the two properties and publish the message to the MessageBox.
  2. The Orchestration would pick it up, perform the transformation, copy the context and send the message out.
  3. The XMLTransmit pipeline would demote the two values from context (that I had copied from the input message) into Field3 and Field4

This didn’t happen, though. No values were demoted at all. Now, not demoting into Field4 was expected, since demotion doesn’t work for attributes (or does it? See my blog post coming up in a very short time :-) ), but I really expected something to turn up in Field3.

It turns out, that this statement from my code:

   1: OutputMessage(*) = InputMessage(*);

does not copy ALL the context, but only the promoted properties that are marked as MessageContextPropertyBase. The ones that are marked as MessageDataPropertyBase (which is the default) do not get copied over. Now, this actually makes sense, all though it baffled me at first, since properties marked as MessageDataPropertyBase are based on values inside the message, so they cannot just be copied to another message type, since BizTalk cannot guarantee that this property exists on this message type and that the element that points to the promoted property actually exists in the message. Well, I guess BizTalk COULD guarantee that, but Microsoft have chosen not to implement that.

Also, distinguished fields, which are also in the context of the message are not copied over – again, this makes sense, since these are tightly bound to the schema they come from (This doesn’t stop the mapping engine of copying them over in maps on receive ports, though, which is really silly – see here).

SO, in order to get ALL the context copied form my input schema to the output schema, I needed three lines of code:

   1: OutputMessage(*) = InputMessage(*);
   2: OutputMessage(DemotionTest.Property1) = InputMessage(DemotionTest.Property1);
   3: OutputMessage(DemotionTest.Property2) = InputMessage(DemotionTest.Property2);

or I could mark the properties as MessageContextPropertyBase.

Yes, indeed… So remember this from now on:

  1. Assigning one message to another does NOT copy over the context
  2. Copying over context using M2(*) = M1(*) does NOT copy over custom properties that are marked as the default (MessageDataContextBase)
  3. In order to get the rest of the properties copied over, do it manually or change the type of the properties, if applicable.

I hope this helps someone…

--
eliasen

Friday, 16 October 2009 13:38:00 (Romance Daylight Time, UTC+02:00)  #    Comments [2]  | 
Friday, 18 February 2011 21:00:44 (Romance Standard Time, UTC+01:00)
Hi,
Since I saw this blog I thought u might be able to help me with this
I was having this wierd issue ..(Ver: Biztalk 2010)
I had an orchestration which is subscribed to the orignal message
1.Copeid this to a new Msg in a construct (Here I am thinking its doing a hard copy and not copying the reference )
2.Called a.net helper and passed in new copied message
3.Changes / filled some proeprties of this message
4.If success publish the changed mesage
5. If failure I actually logging the original message ..Here is the wierd behavior whnen ever an error happen the message is getting published with all the changes to the message till were it errored out as against publishing the original message..Basically its not publishing the new copied message(again I am assuming this was not a copy of the reference and its new hard copied message data)..Looks like its doing a reference copy..
Saturday, 19 February 2011 18:47:42 (Romance Standard Time, UTC+01:00)
Hi Kiran

Well, as you may have guessed by now, it actually does a reference copy and not a hard copy. Consider using a map in a Transform shape to create the new message... or construct the new message inside a Mesage Assignment shape by calling a helper class that creates a new message, copies the content and then changes the values that you need to change.

--
eliasen
All comments require the approval of the site owner before being displayed.
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, sup, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview

Theme design by Jelle Druyts