a trace of thought on...BizTalk Server, Team Foundation Server, AppFabric, etc. RSS 2.0
 Thursday, May 12, 2005

(See update below)

If you have attempted to send email from BizTalk, you’ve gotten pretty comfortable with this documentation topic.

It discusses how to use a sample class (Microsoft.XLANGs.CustomFormattersSDK.RawString) and associated custom formatter to deal with messages that contain raw string content.  As the docs say, “Sending a message of type System.String will not work, because the string gets formatted as an XML document in the message, which is not your desired solution.”  (In other words, whether you send or receive, using System.String as a message type means you are dealing with a wrapping tag.)

However, though the docs cover sending RawStrings, it is less clear how you can use the RawString class when you want to receive messages as such.  Just typing the port operation as RawString will yield a UnexpectedMessageTypeException, because none of the default receive pipelines will set the MessageType context property on inbound messages to be RawString – and this type matching is what orchestrations expect.

We need a custom receive pipeline that will set the MessageType context property equal to the fully qualified type name for RawString.  Jon’s discussion of receiving binary messages provides some background here, and Jon’s ContextAdder pipeline component can make the MessageType context property assignment very easy.

Here are the steps required to receive RawStrings:

  1. Download & build Jon Flanders’ ContextAdder pipeline component, and make sure the build outputs end up in your Microsoft BizTalk Server 2004\Pipeline Components directory.
  2. Build this code (the RawString class & custom formatter) into a separate C# library (with a strong name) and deploy it to the GAC (if you haven’t already when dealing with email.)
  3. Use the RawString type on the orchestration port operation that you are trying to receive RawStrings on…
  4. Create a receive pipeline (ReceiveRawString), and add the ContextAdder pipeline component in the Validate stage.  (You will only ever need one such pipeline around – put it in a common library.)  Configure the properties collection with the properties for RawString, as shown below (“Value” property will be the full five-part assembly-qualified type name):

  5. Specify the ReceiveRawString pipeline for the associated physical port.
  6. Now you will have full access to the raw string content, and can do whatever you need to do…You might want to declare an orchestration variable of type RawString, and assign it to the RawString message so you can access properties/methods like ToString(), which returns the underlying string content.

Update:

Greg Van de Wiele has pointed out the other way to go about this (and Jon has talked about this approach in his recent posts as well.)  It can be less work in that no custom pipeline is required (a one time task) - though perhaps a little harder to explain to the “next guy“...you can decide!

It goes like this:

  1. You will need to do step 2 from above.
  2. Use the XmlDocument type on the orchestration port operation that you are trying to receive raw string content on, and use a PassThruReceive pipeline.
  3. Create a multipart message type, with a single part that is of type RawString.  Also, declare an instance of this type, say, tempRawStringMsg.
  4. Receive the message from the port in step 1 into an XmlDocument-typed message (say, xmlDocIn)
  5. Drag out a message assignment shape.  In the expression, do: tempRawStringMsg.rawString = xmlDocIn;
  6. As before, you might want to declare an orchestration variable (not a message) of type RawString, and assign it to tempRawStringMsg.rawString so you can access properties/methods like ToString(), which returns the underlying string content.

Note that not wrapping the RawString in a multipart message doesn't work - you will get a compiler error indicating that assignments can't be made between XmlDocument and RawString types.  Also note that introducing an intermediate message has a performance cost.

Thursday, May 12, 2005 9:25:39 PM (Central Standard Time, UTC-06:00)  #    Comments [4] -
BizTalk Insights
Friday, May 13, 2005 8:13:31 AM (Central Standard Time, UTC-06:00)
Hey Scott,
I think you can also receive a string as a message of type XmlDocument and assign a RawString variable from this message (RawString = msgIn). I've tried this before with the slight difference that my RawString variable was part of a custom multipart messagetype.
Regards,
Gregory.
Friday, May 20, 2005 1:00:25 PM (Central Standard Time, UTC-06:00)
I used this same technique to create a "PassThru Orchestration", for lack of a better term. An orchestration that receives a non-XML file and sends that same non-XML file back out. Thought someone may find it useful: http://weblogs.randomdust.com/ryan/archive/2005/05/19/354.aspx

Thanks for posting this...it saved me quite a bit of time!
Friday, May 20, 2005 7:42:48 PM (Central Standard Time, UTC-06:00)
You can cast the XmlDocument message to a Rawstring. I've used this technique to deal with some flat file messages that wouldn't work with the flat file assemblers.
Kyle W
Friday, May 20, 2005 7:59:30 PM (Central Standard Time, UTC-06:00)
Hi Kyle - are you describing something different than the update posted? (see bottom of post)
Comments are closed.
Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
About the author:

Scott Colestock lives, writes, and works as an independent consultant in the Twin Cities (Minneapolis, Minnesota) area.

© Copyright 2012
Scott Colestock
Sign In
All Content © 2012, Scott Colestock
DasBlog theme 'Business' created by Christoph De Baene (delarou)