Geeks With Blogs
SOA & Integration Services - BizTalk, WCF, WF, AppFabric etc Why is it drug addicts and computer afficionados are both called users?

An instance of the Biztalk MessageContext is created and stays with each message until the message leaves Biztalk. It contains properties such as RecievePortName, RecieveFileName, MessageType i.e. all the meta data for a message.

If you want to modify this meta data you need to modify the IBaseMessageContext using either the following methods, this may be done in either a custom pipeline component or inside an orchestration:

IBaseMessageContext.Promote: Make the Message Context property a promoted property

IBaseMessageContext.Write: Make the Message Context Property a distinguished property

Where you make the call to modify the message context depends on WHEN it should be modified. If you want to use a message context property to correlate two messages you should do it inside a custom pipeline component. If you want to set the message context during processing after some decision logic do so in a Message Assignment shape in an Orchestration. We are only looking at doing it in a custom pipeline component.

An example of using this would be if you had two input files which needed to be correlated in an orchestration based on an id or date in the filename which defined a relationship between those files. Another example of a problem this would solve is found here: http://www.eggheadcafe.com/ng/microsoft.public.biztalk.server/post21008841.asp

So in both these cases we want to look at the file name of the message, extract and promote part of it so we can either use that extracted information to either correlate two or more incoming messages or base some decision logic on those properties. The way I’m going to show you how to do it is to actually overwrite the RecieveFileName property with the extracted value from it.

Notes:

              I am going to show you how we did it instead of just giving you code or a solution.

              Although I think “Biztalk Server 2004 Unleashed” tries too cover too much in one book it does have a very good explanation of Pipelines and what the different stages of a pipeline should implement.  

1)      Download Martijn Hoogendoorns’ Pipeline Component Wizard http://www.gotdotnet.com/Workspaces/Workspace.aspx?id=1d4f7d6b-7d27-4f05-a8ee-48cfcd5abf4a and install it:

a.       Unzip the source code, open the Visual Studio sln file and rebuild the PipelineComponentWizardSetup project.

b.       Right-click the PipelineComponentWizardSetup project and select “Install” to install it.

2)      In your Biztalk project add a new project and select Biztalk Server Pipeline Component Project set the following properties in the wizard.

3)     Explaining all of the Interfaces which are implemented in a pipeline component is not in the scope of this post. I will   however advise you to take a quick look and familiarise your self with the following methods which implement the PropertyBag: Load, Save, ReadPropertyBag, WritePropertyBag.

The method of the Decode Pipeline Component which does the Biz is the Execute method to which we add the following code:

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)

{

//Make sure the message contexts property name isn't empty

       if (_PropertyName != null)

                     {

              //Get the current value of the property

              object oPropertyValue = inmsg.Context.Read(_PropertyName, _PropertyNamespace);

              if (oPropertyValue != null)

              {

                     string sPropertyValue = (string)oPropertyValue;

                     System.Text.RegularExpressions.Regex oReplaceRegularExpression =

                     new

                     System.Text.RegularExpressions.Regex(_ReplaceRegularExpression);

                                 

                     //Replace the regular expression with the value specified

              sPropertyValue =

              oReplaceRegularExpression.Replace(sPropertyValue,_Value);

                                 

                     //Either promote or distinguish the property

                     if (_PromoteOrDistinguish == "Promote")

                     {

                           inmsg.Context.Promote(_PropertyName, _PropertyNamespace,

                           sPropertyValue);

                     }

                     else if (_PromoteOrDistinguish == "Distinguish")

                     {

                            inmsg.Context.Write(_PropertyName, _PropertyNamespace,

                           sPropertyValue);

                     }

              }

                                                        

return inmsg;

}

Note I have also changed the Value property to allow you replace with an empty string so you can remove characters using a regular expression.

        public string Value

        {

            get

            {

                return _Value;

            }

            set

            {

              if (value == null)

              {

                     _Value = string.Empty;

              }

              else

              {

                     _Value = value;

              }

               

            }

        }

4)     Well that’s the development easy aye thanks to the Pipeline Component Wizard. As for testing I guess you could do this by STOP PRESS a much better way of debugging a pipeline:

              referencing the new pipeline component project in your Biztalk project

              change the output path in the pipeline components project properties dialog to C:\Program Files\Microsoft BizTalk Server 2004\Pipeline Components

              adding the compiled pipeline dll as a component by right clicking on the pipeline component toolbar and choosing add new item then selecting the Biztalk Pipeline Components Tab

              placing a breakpoint in the Execute method code

              add the component to the decode stage of a pipeline where you want to use it set the properties on the decode component to (this is just a suggestion, the regular expression tries to remove all the characters around a date which was in a filename setting the ReceivedFileName property to a date)

              deploy your Biztalk project

              set up a receive port & location

              attach to the BTSNTSvc,exe process

              drop a file in the receive location and hopefully the debug runtime will stop at your breakpoint

5)     To use the modified and promoted RecieveFileName property to correlate two messages

              create a Correlation Type and set the “Correlation Type Properties” property to FILE.ReceivedFileName

              create a Correlation Set based on this type

              initialise the correlation set property of the receive shape (for the messages which need to be correlated) to the name of the correlation set you created above

R. Addis

Posted on Wednesday, April 27, 2005 6:05 AM BizTalk | Back to top


Comments on this post: Building a custom Pipeline Decoder component to modify a Message Context Property

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Hey Mr. synBoogaloo,

First of all, thanks for your blog. It's been very helpful as I try to
get into the world of BizTalk and .NET in general (I have a Java
background).

I have a question for you that should be simple (but I hope not stupid)
enough. I have a simple orchestration that simply converts a input XML
file from schema A to schema B using a map. I noticed, however, that as
soon as the new message (based on schema B) is constructed, I lose the
source file information, such as its name. The result is that by the
time the file is sent to the send port (in this case a FILE folder), its
name becomes %SourceFileName% (instead of the actual name that this
macro should be holding). How do I preserve the original file's name?

I tried to have a message assignment shape with the expression

Message_A(FILE.ReceivedFileName) = Message_B(FILE.ReceivedFileName);

, but that didn't work. What am I missing?

Thank you very much in advance for your help!

Victor P.C.
Left by Victor P.C. on May 31, 2006 8:22 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Hi Victor,
The source file information is in the MessageContext when your
map\transform one file to another the xml data is "transformed over" but
the message context is not. You therefore need to copy over your message
context in an assignment shape like you sort of have done below. To copy
the whole message context use Message_B(*) = Message_A(*);
I also noticed that you had MessageA & MessageB probably the wrong way
round assuming MessageA is the incoming message & MessageB the outgoing.
I would recommend looking calling the DebugView utility from your
message assignment shape to trace the value of RecieveFileName in the
message context of both messages.
Let me know how it goes.
Cheers
Rob
Left by Rob A on May 31, 2006 8:23 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Rob,

You're the man! Your suggestion worked like a charm and the SourceFileName was properly transferred. Once again, thank you for your quick and precise response. Keep up the good work!

Victor
Left by Victor P.C. on May 31, 2006 8:24 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Hi,
I had some problems perhaps someone can point me in the right direction.
I did the following...
- downloaded the Pipeline Component Wizard and installed it.
- Started a new project and selected the Pipeline project (the new on that's there)
- I followed all the steps using the screenshots on the blog.
- When the wizard actually creates the project I get the following error:
-------------------------------------
"System.Runtime.InteropServices.COMEXception(0x80040402):Cannot create project. The project folder '<folderpath>' already exists and contains other files and folders."... etc.
--------------------------------------
But the folder was empty prior to starting the wizard.

Any ideas?
Left by Garth on Nov 06, 2006 9:00 AM

# problem writing xslt
Requesting Gravatar...
Hi,
I have a xml input which has multiple orders with order ids but in one order there can be multiple line items I need to display xml output each order with its information and multiple items listed in input xml file.Can any body help me?
Left by sania on Jan 08, 2007 1:44 AM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Hi Sania,
I think you should invest some time and learn XSLT, writing an XSLT to perform this kind of transformation is actually pritty easy. You just need set the BizTalk Map to use the external XSLT file to perform the transformation.
Left by Rob A on Jan 08, 2007 2:11 AM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Hi,

I am using a map and the transformed xml contains ns0: as prefix and target namespace which I need to remove so it is possible through custome pipeline component.

Please guide me and if anyone can provide me the code that will be great.

Thanks
Left by Rahul on Jan 10, 2007 2:00 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Use an external XSLT to remove the namespace prefix easier than writing a pipeline component.
Left by Rob A on Jan 10, 2007 7:14 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
I have used this wizard to create a send pipeline component. When I try to use the custom component that I have built in a pipeline I am getting the following error
Event ID 5720
there was a failure executing the send pipeline: "Unknown" Source: "Unknown" Send Port: <my port> Reason: The pipeline lading failed due to database error.
Does anybody know what could be causing this?
Thanks
Left by Co on Feb 12, 2007 12:29 PM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
Use this link http://www.codeplex.com/btsplcw in future search codeplex for all the GotDotNet Urls.

Cheers
Rob
Left by Rob on Mar 11, 2008 4:37 AM

# re: Building a custom Pipeline Decoder component to modify a Message Context Property
Requesting Gravatar...
So good.one of the awesome posts I have ever seen in this forum. I found this very much useful for my future work.Thank you very much . http://www.clothingseries.com discount gucci t shirts to us!!
Left by Welcome on Jun 10, 2010 8:04 PM

Your comment:
 (will show your gravatar)


Copyright © Rob Addis | Powered by: GeeksWithBlogs.net