Set Dynamic Destination File Name With BizTalk Server 2006


I’ve been asked a couple times recently about generating message out of BizTalk Server with a dynamically-set file name. Here
are 3 primary ways of setting this value.

In the scenario I built here, it’s a basic “stock order” situation, where the order is received, and an output file is created
with a file name that adheres to a format of <date><ticker symbol>.xml. My “order” schema has a few elements,
and the “ticker symbol” element has been both promoted and distinguished.

Option #1. This is arguable the easiest. Take the message in, create a dynamic send port, and use an Expression Shape
to set the Address of the file drop, including the file name. Here I created a simple date string and appended the distinguished
“symbol” field to build the file name.


As expected, the output file was generated.


Option #2. Let’s say you want the send port pre-configured as a FILE port and don’t want to dynamically set all the values of
the port. Well, what you can do is create a copy of your incoming message (via Message Assignment) and then set the context
value FILE.ReceivedFileName to your dynamically generated name. The FILE.ReceivedFileName is assigned when the FILE
adapter receives a message. It contains the physical name of the inbound file.



This comes into play in the FILE send port where you can use the token %SourceFileName% as the destination file name. That token
uses the FILE.ReceivedFileName value. So what we’ve done is set the value in our orchestration that this token will use when
writing the file out. Once again, after running this version I get the file output with the expected name.

Option #3. Let’s say you have a “messaging-only” solution and no need for orchestration. In that case, you can use a simple
custom pipeline component to do the same thing we did in Option #2. I created a basic custom send pipeline component which sets the
value of the FILE.ReceivedFileName using the code below …




public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)

{

//set friendly date string

string dateString = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString();

//create pointer string

string tickerString = “”;

string fileString = “”;

//get value of ticker symbol that’s been promoted

tickerString = Convert.ToString(inmsg.Context.Read(“Symbol”, “http://Microsoft.Blog.DynamicOutput.PropSchema”));

//build outbound file name

fileString = dateString + tickerString + “.xml”;

//write updated value back to context

inmsg.Context.Write(“ReceivedFileName”, “http://schemas.microsoft.com/BizTalk/2003/file-properties”, fileString);

//return the message with modified context

return inmsg;

}

Once that component is compiled and made available to Visual Studio, you create a Send Pipeline and drop our little component in there,
like so …


And I get the same file name as the other two options. So, it’s fairly easy to manipulate the destination file name using either
dynamic ports or playing with context values. Any other options I missed?

Technorati Tags:

Comments (8)

  1. Richard,

    Though its not the best solution (and probably not supported), you could also promote your schema field to the Microsoft.BizTalk.GlobalPropertySchemas (FILE.bts_file_properties) field and overwrite the value in that field.  Here are sample instructions:

    a.  Create the message schema

    b.  On the field that will contain the filename, choose show promotions (this is assuming that you haven’t already promoted this field)

    c.  We will be using the BizTalk internal file property schema:  Choose References -> Microsoft.BizTalk.GlobalPropertySchemas -> Schemas -> FILE.bts_file_properties

    d.  Click on the add button to add the your field to the property fields list

    e.  Leave the  node path ‘as is’, but change the Property to point to ns0:ReceivedFileName

    f.   Use the %SourceFileName% macro in your send port.

  2. That’s very true.  However, you’re assuming that the file name you want is stored in a field in the XML doc.  If so, then this would work well.

  3. Gaurav Garg says:

    Hi,

    i read your description abt %SourceFileName%. and tried using the #option2. But I have a query:

    I have created a send message "Testver7SendMsgInc"

    and receive message named "Testver7RecMsgInc"

    When i type the following code in the Expression Editor

    Testver7SendMsgInc = Testver7RecMsgInc;

    i get the following error:

    Cannot implicitly convert type ‘message Testver7Schemas.XMLInputFile1’ to ‘message Testver7Schemas.FlatFileSchema1’

    And below it when i type:

    Testver7SendMsgInc(FILE.ReceivedFileName) = System.Convert.ToString(Testver7RecMsgInc.ACTSEQ);

    I get the following error:

    identifier ‘ACTSEQ’ does not exist in Testver7RecMsgInc’; are you missing an assembly reference?

    ACTSEQ is my child field element.

    Well one thing i would to tell you is that my input schema ie XMLInputFile1 and output schema ie FlatFileschema1 and and map are in one project while orchestration which has both Testver7SendMsgInc and Testver7RecMsgInc in another project in the same solution. I have referenced my schema project in the orchestration project.

    Pls tell me what is the problem.

    Basically i want to get the value of ACTSEQ ie is a child field element, which i am getting from an XML file, to be shown as a name in my output file ie is a .txt file.

    i also tried what # Brennan O’Reilly said on July 12, 2006 1:26 PM: Microsoft.BizTalk.GlobalPropertySchemas (FILE.bts_file_properties).

    But i get my output file with name as %SourceFileName%.txt and not as required.

    Pls tell me the solution.

    Thanks, waiting for ur reply.

    Gaurav Garg

  4. Ok, there’s like 4 questions in there.  First off, you can’t use the "Message Assignment" to set one message equal to another, unless they are of the same TYPE.  I can’t set an XML message of one format equal to a different XML message of an additional type.  Make sure that ACTSEQ is a "distinguished field".  Otherwise, the orchestration error will tell you it can’t see that value.  Try that and see what happens.

  5. Gaurav Garg says:

    Hi rseroter,

    Thanks for ur reply. Ok i can’t assign "Message Assignment" in my case.

    I have tried making ACTSEQ as distinguished field. but still of no use. Or still i have to do anything else,  pls if you could explain me in details what should i do to the value of one my child field element node as an output file name?

    I am running out of time and got no solution. Pls if you could help me.

    Hope to receive a positive response from your side.

    Thanks

    Gaurav Garg

  6. How come you cannot make ACTSEQ a distinguished field?  Is it a repeating element in your schema?  If it is, then you use a custom pipeline component and grab the instance of the repeating field.  Or, you write a .NET component that takes in the XML node list and pulls out the value you want.