Creating a BizTalk 2006 R2 VPC Template for Use in MS System Center Virtual Machine Manager


I was tasked with the objective of creating a way for the EAI group to "mass-produce" BTS2006 R2 servers on the corporate Virtual Server Self-Serve portal for development purposes. Note that before embarking on this task, make sure that you or your company has the appropriate licenses (MSDN or other) to set this up.

In analyzing the requirements for this, I found out that I would need to create a VPC with all the software on it. This VPC would then be processed and imported into the self-serve portal as a "template" for all machines to be made from. However, I found out some interesting information about the process the VPC is run through as it's being made into a "template".

The VPC is first run through an application named SysPrep. This software "anonymizes" the OS. It removes the Windows activation code and also removes all the Security Identifiers associated with all files and accounts. This means that any "non-system" accounts created before SysPrep is run will not match the accounts after SysPrep is run. This brought up the major issue I ran into while trying to complete this objective. While configuring both BizTalk and Windows SharePoint Services (WSS), you need to provide accounts, which will be the owners of the associated processes. The issue would be that any account(s) I create and configure before SysPrep is run would not match the account(s) on each instantiation of the template, since the security IDs associated with the accounts wouldn't match.

During discussions about this issue, someone theorized about possibly installing all the software, but not configuring the ones that need specific accounts (BTS 2006 and WSS 2.0/3.0). That's when I tried going through the Microsoft Installation instructions for BTS 2006 R2 (
http://www.microsoft.com/downloads/details.aspx?FamilyID=df2e8a88-fb23-49a4-9ac7-d17f72517d12&displaylang=en). In order to create a "template" for the Self-Service Portal, I created a VPC, with all the software products installed. I started with Windows Server 2003 (Enterprise). I changed the order in one aspect, in that they instruct you to install Windows 2003, then run Windows Update, and then install IIS. What I did was to install Windows Server 2003, then install IIS and the POP3 service, and then run Windows Update, so that I could get any update files specifically marked for IIS or the mail server.

After I did that, then I installed the Office Components. The instructions specified Excel and InfoPath, but I also included Word. However, one note on these components. During installation, I did not use a Product Key for Office. This was so that whoever needs to use the server can use their own Office product key.

I then installed Visual Studio 2005, and then service pack 1 for VS 2005. I did add a feature not listed in the instructions. The instructions indicate that you should unselect all features except Visual C# and .Net Framework SDK. I did keep the Visual Web Developer component, in case any web services needed to be included in any project.

At this point, the instructions indicate that SQL Server 2005 should be installed. Now, one option in the installation for SQL allows for the use of a separate account, under which SQL server will run. Another option allows for SQL Server to run under a "defined system account". I chose this option because, when the VPC/VHD is imported and converted to a template for use in the Self-Service portal, the SIDs are all stripped out of accounts, so an account created now would not match an account when the template is "instantiated" into a particular instance.

At this point, I added the additional software packages requested to be on the server, including NUnit and BizUnit.

The next step includes installing first, Windows SharePoint Services (WSS) 3.0, and then WSS 2.0. Both versions were installed because the BAM portal in BTS 2006 is only supported on WSS 2.0, but most project work moving forward will likely be done on WSS 3.0. Thus, if you want to have the BAM portal on the same box that you have a WSS 3.0 site (or MOSS 2007 site), you need to have both versions of SharePoint installed. Note that after the installation is completed, the instructions indicate that configuration is next. Because user accounts are involved in the create of Application Pools when using WSS on IIS, this step was "postponed" until a particular instance was created.


The last software package installed was BizTalk Server 2006 R2 itself. I went through all the steps and did all the installation, but on the last screen, where the checkbox indicating that the configuration wizard should run after setup is completed, I unchecked this so that it could be done on a per instance basis.

After everything was done, I defragmented the hard drive, ran the pre-compaction utility, and then compacted the drive. This allowed for a smaller VHD for import and cleaned up a lot of space in the VHD after all the updates had been made.

Mapping With External Assemblies Part 2

Introduction

Part 1 - Inline scripting and external assemblies
Part 2 - XSLT Call Templates and custom extensions
Part 3 - Cascading Functoids

This is the second of three articles about BizTalk mapping with external assemblies. External assemblies or helper classes are used by BizTalk's mapping engine (XSLT) automatically, and they can also be used explicitly by the developer. Just as in an orchestration, a developer may find a requirement that the built in mapping tools ("functoids") do not address and in this case judicious use of a helper class can be very... helpful.

While these articles are not an introduction to mapping if you have a little experience with the BizTalk mapper and a little experience with XSLT you should be able to follow along.

Part 1, introduces inline C# scripting, its limitations, and also introduces the scenario of using an external assembly (helper class) automatically. Part 2, this article, demonstrates using a map's custom extension property, which allows us to explicitly access external assemblies. Part 3 will build on this discussion and highlight potential caveats about using cascading functoids; when the output of one functoid  is the input to another functoid(s).

External Assembly Script Type Review

In part 1 we examined inline scripting with C# and pointed out that only the built-in XSLT engine namespaces can be used. We also showed that when using an External Assembly Script Type an Extension Object XML file is automatically created, which contains the external assembly references that the XSL will use.

The contents of the Extension Object Xml file that is made during the build looks like this:

<ExtensionObjects>
  <
ExtensionObject
      Namespace=
"http://schemas.microsoft.com/BizTalk/2003/ScriptNS0"
      AssemblyName="
RDA.BizTalk.Learning.MapUtility,
          Version=1.0.0.0,
          Culture=neutral,
          PublicKeyToken=f7eb52812c0b3fa1
"
      ClassName="RDA.BizTalk.Learning.MapUtility.Strings"
/>
</
ExtensionObjects>


Custom Extension Xml Property

imageIf we want to explicitly include external assemblies in our map we can assign the "Custom Extension Xml" Grid Property. Click on the background (grid) of your map in design mode to find the properties. The property represents an Xml file that is formatted as shown above, and it will contain only those assemblies that you wish to manually reference. As we will see, other assemblies referenced by External Assembly Script Types will be automatically appended to this file during the build.

I normally name my file "External Assemblies.xml". The following is an example. I usually leave the Namespace as the Namespace of the class.  That way if I have one assembly (as I do below) I will have 2 unique namespaces. Remember, your external assemblies are probably already in the GAC.

<ExtensionObjects>
    <
ExtensionObject
        Namespace=
"http://RDA.Corporate.EAI.Common.Helper.Methods.Timestamps"
        AssemblyName="
RDA.Corporate.EAI.Common.Helper.Methods,
                     
Version=1.0.0.0,
                      Culture=neutral,
                      PublicKeyToken=9f177c4f1a417459
"
        ClassName="RDA.Corporate.EAI.Common.Helper.Methods.Timestamps"
/>
    <
ExtensionObject
        Namespace="http://RDA.Corporate.EAI.Common.Helper.Methods.DBUtility"
        AssemblyName="
RDA.Corporate.EAI.Common.Helper.Methods,
                      Version=1.0.0.0,
                      Culture=neutral,
                      PublicKeyToken=9f177c4f1a417459
"
        ClassName="RDA.Corporate.EAI.Common.Helper.Methods.DBUtility"/>

</ExtensionObjects>

Using the Referenced External Assemblies

We already know that unfortunately we cannot use these classes with inline C# scripting. However, we also know that ultimately the mapper is simply creating XSLT and calling the C# methods, and we can do the same.

Let's pretend, for example, that based on a meeting number, room number and timestamp that I need to retrieve a meeting record id. My DBUtility class contains the methods I need to use.

  1. Add a reference for the RDA.Corporate.EAI.Common.Helper.Methods assembly.
  2. Create and add External Assemblies.xml file (named to your liking) to your map project.
  3. Assign the Custom Extension XML Grid Property.
  4. Add a scriptoid to your map.
  5. Set it's script type to XSLT Call Template.
  6. Assign input parameters, and assign the output to the target schema node as required.

Here is my map, I'm going to enrich the original message by filling in the MeetingKey record. I'll be using an XSLT call template. Remember it is the XSLT that is driving the mapping within the scriptoid. See the next paragraph.


image 


Here is my XSLT call template that I've assigned to my scriptoid shown above.

<xsl:template name="MeetingKeyCallTemplate">

    <!--
Meeting Key Input
-->
    <
xsl:param name="meetingNumber"
/>
    <
xsl:param name="roomNumber"
/>
    <
xsl:param name="meetingTimestamp"
/>

    <!--
Get the meeting key and assign it to variable
-->
    <
xsl:variable name="meetingKey"  
       
<!-- I'll just use the prefix "script" which is easy to type --> 
        xmlns:script="http://RDA.Corporate.EAI.Common.Helper.Methods.DBUtility"
        <!-- Call my external method GetMeetingKey() -->                  
        select="script:GetMeetingKey($meetingNumber,
                       $meetingTimestampDateTime,
                       $roomNumber)
"
/> 

    <!--
Emit the MeetingKey and modified attribute values
--> 
    <MeetingKey>
        <
xsl:attribute name="modified">Yes</xsl:attribute
>

        <
xsl:element name="id"
>
            <
xsl:value-of select="$meetingKey"
/>
        </
xsl:element
>
    </
MeetingKey


   
<!--
Emit the MeetingNumber, RoomNumber and MeetingLeader fields --> 
    <MeetingInfo>
        <
xsl:element name="MeetingNumber"
>
            <
xsl:value-of select="$meetingNumber"
/>
        </
xsl:element
>

        <
xsl:element name="RoomNumber"
>
            <
xsl:value-of select="$roomNumber"
/>
        </
xsl:element
>

       <!-- Note: The MeetingLeader value comes directly from the original message  -->
      
<xsl:element name="MeetingLeader">
            <
xsl:value-of select="MeetingInfo/MeetingLeader/text()"
/>
        </
xsl:element
>
    </
MeetingInfo
>

</
xsl:template>

TIP: In part 3 we'll see similar code again and we will combine into one example the use of external assemblies, inline C# scripting and value caching in a discussion about cascading functoids.

Custom Extension XML and External Assembly Script Types

The BizTalk mapper will accommodate maps using both custom Extension XML file as described here and also uses External Assembly Script Types. In this case the Extension Object XML file that is used will combine your custom references along with the automatically added External Assembly Script Type references. Validate your map and check it out!


External Links from MSDN


External Links about BizTalk Mapper Performance

Mapping With External Assemblies Part 1

Introduction

Part 1 - Inline scripting and external assemblies
Part 2 - XSLT Call Templates and custom extensions
Part 3 - Cascading Functoids

This is the first of three articles about BizTalk mapping with external assemblies. External assemblies or helper classes are used by BizTalk's mapping engine (XSLT) automatically, and they can also be used explicitly by the developer. Just as in an orchestration, a developer may find a requirement that the built in mapping tools ("functoids") do not address and in this case judicious use of a helper class can be very... helpful.

While these articles are not an introduction to mapping if you have a little experience with the BizTalk mapper and a little experience with XSLT you should be able to follow along.

Part 1, this article, introduces inline C# scripting, its limitations, and also introduces the scenario of using an external assembly (helper class) automatically. Part 2 demonstrates using a map's custom extension property, which allows us to explicitly access external assemblies. Part 3 will build on this discussion and highlight potential caveats about using cascading functoids; when the output of one functoid  is the input to another functoid(s).

Inline Scripting with C#

As you probably know, using C# within a map is very easy to do. Drag the scripting functoid to the map:


From Toolbox to Design Window   

Right click on the scripting functoid and add your C# code:


From Funtoid Menu to Script Dialog 

Tip: In a previously saved map, if you switch between Script Types be sure to click the Reset button first, otherwise old settings (including C# code!) will stick around and the Script Type property won't necessarily change even though there is no warning.

Tip: You can display friendly names for your input parameters if you set the Label property for each link.  View the link properties by clicking each link (line) in the map.

Unlabeled Links
Configure Functoid Inputs 1 

Label Property
Link Properties

Labeled Links
Configure Functoid Inputs 2

Limitations of Inline Scripting

Validate Map Once the map is completed we can validate it and view the generated XSL file. I encourage you to create a simple map, validate it, then look at the resulting XSL file... even if you know only a smattering of XSLT you can gain lots of insight into how the actual mapping is working (or not!).

If we look at the XSL file from the map above we discover that the BTS Mapper puts all of our inline C# code into a CDATA section. There is a screenshot below. Then within an XSLT statement our C# method is called. This is actually the key to the whole series of articles! In this case the BTS Mapper designed the XSLT extended syntax for us, but as you will find out in part 2 we can do it for ourselves!

So, why would we ever want to do manually what the BTS Mapper can do for us automatically? Well, if you reflect on the above paragraph you'll notice that our C# method is called from an XSLT statement. To highlight this point, below are the snippets from the XSL of our map:

This section is how the XSL inline C# is automatically defined within a CDATA section. Noticed the prefix "userCSharp" as in the future this will come in handy.

<
msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
    public string MyInlineSortKey(string str1, string str2)
    {
        const string comma = ",";
        return String.Concat(str1, comma, str2);
    }
]]></msxsl:script>


Here is the actual XSLT that is generated. A variable named "v1" is created and our method is called by passing the XPATH values of LastName and FirstName. The actual use of the C# method is very straight forward.

<xsl:variable name="var:v1"
              select="userCSharp:MyInlineSortKey(string(Customer/LastName/text()),
                      string(Customer/FirstName/text()))
" />
<
SortKey>
    <
xsl:value-of select="$var:v1" />
</
SortKey>

To come back to the question, why would we want to implement a call to a helper class manually? It's because there are limitations to what you can do with inline C#. Specifically, inline C# that looks like the following will not compile even if the MyMapUtility reference was added to the map project.

MyMapUtility.Strings stringUtil;
return
stringUtil.MySortKey(str1, str2);

From MSDN (references at end):

BizTalk saves inline scripts in the Extensible Stylesheet Language Transformations (XSLT) stylesheet defining the map. Because of this, inline scripts may use the same namespaces as any other XSLT stylesheet script.

What this means is that even if you add the helper class reference to your map project, you will not be able to call your methods with inline scripting and the map project will not compile. Part 2 will cover how this can be accomplished using XSLT call templates. Here are the namespaces that are supported for inline scripting, so remember with inline C# scripting you can use these namespaces but no other:

Supported namespaces for inline scripting
Namespace Description
System The System class
System.Collection The collection classes
System.Text The text classes
System.Text.RegularExpressions The regular expression classes
System.Xml The core XML classes
System.Xml.Xsl The XSLT classes
System.Xml.Xpath The XPath classes
Microsoft.VisualBasic The Visual Basic script classes.

External Assembly Script Types

Script Type External AssemblyAs we've examined, inline C# scripting only supports a certain set of namespaces. And in part 2 we'll look at custom XSLT templates that let use use any external assembly. However, there is functionality out of the box that the BTS mapper provides for using External Assemblies.

The main caveat is that the default constructor (parameterless) on the external class will be used. In some cases you may find yourself wanting to create a wrapper class created especially for mapping that handles a custom initialization of the actual helper class.

Knowing how the External Assembly and method call is incorporated into the map will help us in part 2 when we describe manually using an external assembly.

Here is a example helper class that is designed to return two strings separated by a comma. After creating the helper class add its reference to the Map project.

Typical helper class. This method will take two inputs and return a value:

namespace RDA.BizTalk.Learning.MapUtility
{
    ///
<summary>
    ///
String Utilities
    ///
</summary>
    [Serializable]
    public class
Strings
    {
       
// A custom sort key
       
//
        public string MySortKey(string str1, string str2)
        {
            const string comma = ",";
            return String.Concat(str1, comma, str2);
        }
    }
}


Assign the External Assembly to your scriptoid and pick your class method:
image
TIP:
If you right click and "Test" a map that uses an external assembly, the assembly must already be added to the GAC, otherwise the test will fail.

Validate MapNow let's examine what the mapper does with the external assembly to call it. We can do this by right clicking the map and picking "Validate". The output of the validation process is the XSL file and an Extension Object XML file.

The Extension Object XML file was created automatically based on all the external assemblies used in the map (in this case, just one). It contains the assembly reference that the XSL will use. It looks like the following:

Extension Object XML:

<ExtensionObjects>
  <
ExtensionObject
      Namespace=
"http://schemas.microsoft.com/BizTalk/2003/ScriptNS0"
      AssemblyName="
RDA.BizTalk.Learning.MapUtility,
          Version=1.0.0.0,
          Culture=neutral,
          PublicKeyToken=f7eb52812c0b3fa1
"
      ClassName="RDA.BizTalk.Learning.MapUtility.Strings"
/>
</
ExtensionObjects>

Now, let's examine the XSL file. It turns out that the use of the external assembly will look almost exactly like how the inline C# code was called. The only difference is that in this case in the header of the XSL file a namespace alias is created for "ScriptNS0". I encourage you to validate your own simple map that uses an external assembly.

External Assembly XSLT:

<
xsl:variable name="var:v1"
             
select="
ScriptNS0:MySortKey(string(Customer/LastName/text()),
                      string(Customer/FirstName/text()))
"
/>
<
SortKey
>
    <
xsl:value-of select="$var:v1"
/>
</
SortKey
>


The inline C# code XST from the previous section for comparison:

<
xsl:variable name="var:v1"
              select="
userCSharp:MyInlineSortKey(string(Customer/LastName/text()),
                      string(Customer/FirstName/text()))
"
/>
<
SortKey
>
    <
xsl:value-of select="$var:v1"
/>
</
SortKey
>

TIP: The "userCSharp" prefix is used for all of your inline methods. If you have your own inline XSLT transformations you can call previously defined inline C# methods yourself!

TIP: Though not necessarily a best practice it is possible to create a "floating" scriptoid (not connected to anything!) that just contains a few methods (yes, more than one) that you will call elsewhere in the map. You can call them from custom XSLT, and you can also call them from inline C#! In this manner you could have a GET and SET method to cache calculated values that are valid during the execution of the map.

TIP: A scriptoid must have a least one output to the target schema in order to be executed by the XSLT map. Otherwise, the map will still compile however the scriptoid will not execute.

External Links from MSDN


External Links about BizTalk Mapper Performance

BizTalk Tracking Advantages

BizTalk allows tracking to be configured at receive, send port and orchestration levels to monitor transaction activity, flow and to access message contents. As long as tracking is enabled at least on one host, all tracked transactions will use that host for tracking (by default, BizTalkServerApplication host is designated for tracking). So it’s not necessary that a tracking host be assigned in a specific application to receive, send ports and orchestrations. Reason being, a message agent that is running within each BizTalk host will be calling a stored procedure that searches through each of the messages in the Messagebox looking for messages with matching subscription information. To keep the Messagebox as empty as possible, the tracking subsystem will move completed messages to the Tracking Database on a periodic basis. The Tracking Database is where the HAT queries for data and displays its tracking information. This is accomplished by a BizTalk host that has been tagged as a “tracking” host.

For most BizTalk customers, tracking data is very important for the following reasons:

  • To comply with federal guidelines Sarbane-oxley, IRS and such
  • To satisfy accounting department requirements to generate reports for business users, for example using BAM tracking
  • In the case of failures and such, to help recover from a disaster, because it is a record of data processing activity
  • Data in the tracking databases can be used to help determine the state of the system up to the point of failure for the runtime databases
  • Tracked messages and events can indicate what processes may have already happened and what messages have been received or sent
  • Tracks the health and run history of BizTalk messages and orchestration processes and aids in identifying errors and bottlenecks in the BizTalk Server environment
  • Individual tracking information per message can correlate what types of transactions are taking the most time
  • To view the technical details of a particular orchestration, pipeline, or message instance, as well as to see the message flow of a particular message from end to end
  • Tracking facilitates troubleshooting of service instances and messages
  • It provides debugging capabilities, allowing breakpoints to be set on orchestration shapes
  • Business users can view, monitor, and query completed messages and processes via tracked data, saving these queries as custom views for reuse
  • Business analysts and end users can track the state of their business processes by viewing both live and archived data

Reference: Apress Pro BizTalk 2006 book

BizTalk performance issues

Recently one of our customer experienced performance issues with BizTalk, where transaction queues were filling up and it was taking too much time to process normal transaction activity. So I went onsite, checked the obvious, found two familiar performance related issues...

Issue 1:Verfied built in SQL jobs history, found that DTA Purge and Archive (BizTalkDTADb) has not run on the production BizTalk server since September 2007. BizTalk tracking data file was about 1.6GB, obviously, which results in performance degradation. Analysis: DTA Purge and Archive SQL job is expected to run every day (24 X 7) about 15-20 minutes apart. As time goes, the BizTalkDTADb database will grow in size and unchecked growth will result in poor performance. Possibly having an adverse impact on message box database performance as well...

Resolution: Followed the steps detailed in this MSDN article:
http://technet.microsoft.com/en-us/library/aa560754.aspx
exec dtasp_BackupAndPurgeTrackingDatabase
0, --@nLiveHours,
30, --@nLiveDays
35, --@nHardDeleteDays
‘\\D:\SQL backup’, --@nvcFolder
null, --@nvcValidatingServer
0 --@fForceBackup Soft purge process
After performing the steps above (once the tracking data is purged) "DTA Purge and Archive (BizTalkDTADb)", set the SQL Job is enabled and is running at every 20 minutes. Database size came down to 30 MB from 1.6 GB!
To Understand DTA Tracking performance behavior, refer to these MSDN article:
http://msdn.microsoft.com/en-us/library/cc296718.aspx


Issue 2: There were three BizTalk hosts in the production environment including the default BizTalk host instance and other two being txHost1 and txHost2. All the three host instances had tracking turned on.
Analysis: According to BizTalk documentation, "Allow host tracking" check box must be enabled on a single host instance and ideally on the default in-process BizTalk Application Host. "Allow host tracking" should not be enabled on any other Host instances.
Resolution: Removed tracking from txHost1 and txHost2 hosts, kept it unchanged on the BizTalk Application Host and restarted all the three hosts.
Creayed and configured three new host instances such as orchHost for all orchestrations, rcvHost for all receive locations and sndHost for all send ports. Tested on the QA server with 1577 transactions, it took about 17 minutes to process all transactions, thus processed about 100 transactions a minute, improving the performance significantly...

For more info on tracking host: http://msdn.microsoft.com/en-us/library/cc296878.aspx

Consuming a Java Web Service (JWS) Method Containing String Arrays as Parameters

Consuming a Java Web Service (JWS) Method Containing String Arrays as Parameters

Recently I was working on a POC where one of the tasks was integrating with a Quality Control application that exposed a web service built with Java. The application used a JWS to expose web service methods that were RPC encoded. BizTalk Server 2006 and Visual Studio 2005 natively recognized and imported the JWS WSDL and generated a multi-part message in the BizTalk project.

Early in the POC, consuming, connecting and executing the process were demonstrated using a JWS method called, Sample Log. There was no issues importing the JWS WSDL but the challenge was populating the message since it used string arrays for parameter names and values.

Multi-part Message Types
The multi-part message type generated by importing the SampleLog WSDL are the last invoke_request and invoke_response in the figure below. We will take a closer look at the invoke_request message because the fieldsArrayC and valuesArray C items for the invoke_request message are actually string arrays. This message structure presents a challenge for BizTalk because although this message type was successfully generated in BizTalk, it was not available for use within the Mapper.


Using and populating the message structure
In order to use and populate the mutli-part message in BizTalk, 3 three messages needed to be defined to get around the limitations of the mapper.
These are:

  1. msgLIMSSampleLogRequest - Message that will be sent to the JWS.
  2. msgLogSampleReferenceNameArray – An array that contains the names of the parameters passed. This message structure will be added to the msgLIMSSampleLogRequest message.
  3. msgLogSampleReferenceValueArray – An array that contains the values of the parameters passed. This message structure will be added to the msgLIMSSampleLogRequest message.

    Create Message Variables

Orchestration Snippet
Because we can’t use the mapper, an orchestration must be used. In the orchestration, the msgLogSampleReferenceValueArray and msgLogSampleReferenceValueArray needed to be populated using the following code in the Expression Shape of the orchestration.

Once msgLogSampleReferenceValueArray and msgLogSampleReferenceValueArray messages were populated, they could be assigned to the msgLIMSSampleLogRequest message as described in the next section.

NOTE: This code is for demonstration purposes only. An actual implementation would use a component or other solution to populate the array depending on the requirements.

System.Diagnostics.Debug.WriteLine(System.String.Format("{0}{1}: {2}", strInterfaceName, "BuildReferenceArrays", ""));

//Format and Populate ReferenceName
strParameters = System.String.Format("{0},{1},{2},{3},{4},{5},{6},{7}", "LOT", "LOT_NAME", "PRODUCT_GRADE", "DESCRIPTION", "ROLL", "SAMPLING_POINT", "SPEC_TYPE", "GROUP_NAME");
System.Diagnostics.Debug.WriteLine(System.String.Format("{0}{1}: {2}", "strParameters", "strParameters", strParameters));

objXmlDoc1 = new System.Xml.XmlDocument();
objXmlDoc1.LoadXml
(@"

LOT
LOT_NAME
PRODUCT_GRADE
DESCRIPTION
ROLL
SAMPLING_POINT
SPEC_TYPE
GROUP_NAME

"
);

msgLogSampleReferenceNameArray = objXmlDoc1;


System.Diagnostics.Debug.WriteLine(System.String.Format("{0}{1}: {2}", strInterfaceName, "ReferenceNameArray", objXmlDoc1.InnerXml));

//Format and Populate ReferenceValue
strParameters = System.String.Format("{0},{1},{2},{3},{4},{5},{6},{7}", "89210", "1000222", "40786351", "S 901/ERL 1908 HM", "001", "6351ANYL", "SP_1", "WINONA");

objXmlDoc2 = new System.Xml.XmlDocument();
objXmlDoc2.LoadXml
(@"

89210
1000222
40786351
S 901/ERL 1908 HM
001
6351ANYL
SP_1
WINONA

"
);

msgLogSampleReferenceValueArray = objXmlDoc2;

System.Diagnostics.Debug.WriteLine(System.String.Format("{0}{1}: {2}", strInterfaceName, "ReferenceValueArray", objXmlDoc1.InnerXml));


Populate Main Message (LogRequest)
The final step is to populate the msgLIMSSampleLogRequest message in an Expression shape. Within the Expression shape the fieldsArrayC element is loaded with the msgLogSampleReferenceNameArray and the valuesArrayC element is loaded with the msgLogSampleReferenceValueArray.

The following is the code snippet that loads the message. The highlighted rows are where the string arrays from the previous step are actually loaded into the main message.

msgLIMSSampleLogRequest.authToken = msgLIMSAuthenticate1Response.authenticate1Result;
msgLIMSSampleLogRequest.templateNameC = "SPEC_IPL";
msgLIMSSampleLogRequest.fieldsArrayC = msgLogSampleReferenceNameArray;
msgLIMSSampleLogRequest.valuesArrayC = msgLogSampleReferenceValueArray;

New BizTalk Server and Enterprise Single Sign-On Custom Configuration Whitepaper Available

We’ve published a new whitepaper on our RDA corporate website dealing with the issue of how to store custom configuration information on an enterprise level, and for large numbers of different projects.

Over time, we’ve tried a number of different scenarios to solve this need and have settled on a useful approach by using Enterprise Single Sign-On. There is a need for a central repository for configuration information to avoid multiple copies of configuration information stored on specific servers and to increase security.

The whitepaper, titled Microsoft BizTalk Server and Enterprise Single Sign-On Custom Configuration discusses topics surrounding custom configuration within SSO with the intention of providing understanding and a reference point on utilizing it.

You can also read our other RDA whitepapers.