<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>.RICHARD</title>
	<link>http://www.richardhallgren.com</link>
	<description>Scribbles on .NET, BizTalk and integration etc ...</description>
	<pubDate>Wed, 16 Jul 2008 11:51:58 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Efficient grouping and debatching of big files using BizTalk 2006</title>
		<link>http://www.richardhallgren.com/efficient-grouping-and-debatching-of-big-files-using-biztalk-2006/</link>
		<comments>http://www.richardhallgren.com/efficient-grouping-and-debatching-of-big-files-using-biztalk-2006/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 10:06:06 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[Sample code]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/efficient-grouping-and-debatching-of-big-files-using-biztalk-2006/</guid>
		<description><![CDATA[I&#8217;ve seen people struggle both on the forums and while doing consulting when in it comes to finding an good way of grouping and transforming content in file before debatching it. Say for example we have a text file like the example below.


0001;Test row, id 0001, category 10;10
0002;Test row, id 0002, category 10;10
0003;Test row, id [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve seen people struggle both on the <a href="http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3564558&amp;SiteID=1" target="_blank">forums</a> and while doing consulting when in it comes to finding an good way of grouping and transforming content in file before debatching it. Say for example we have a text file like the example below.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:fc281aed-59e1-46a7-a832-b54443a6f5f9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #000000; ">0001</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0001</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0002</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0002</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0003</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0003</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0004</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0004</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">20</span><span style="color: #000000; ">;</span><span style="color: #000000; ">20</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0005</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0005</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">20</span><span style="color: #000000; ">;</span><span style="color: #000000; ">20</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0006</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0006</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">20</span><span style="color: #000000; ">;</span><span style="color: #000000; ">20</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0007</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0007</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">20</span><span style="color: #000000; ">;</span><span style="color: #000000; ">20</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0008</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0008</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0009</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0009</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">10</span><span style="color: #000000; ">;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">
</span><span style="color: #000000; ">0010</span><span style="color: #000000; ">;</span><span style="color: #000000; ">Test row</span><span style="color: #000000; ">,</span><span style="color: #000000; "> id </span><span style="color: #000000; ">0010</span><span style="color: #000000; ">,</span><span style="color: #000000; "> category </span><span style="color: #000000; ">30</span><span style="color: #000000; ">;</span><span style="color: #000000; ">30</span></div>
</pre>
</div>
<p>Notice how the the ten rows belong to three different categories (10,20 and 30). These kind of export are in my experience quite common batch export from legacy systems and they usually aren&#8217;t ten rows (in my last project the sizes ranged from 5 MB to 25 MB) &#8230; </p>
<h3>The problem</h3>
<p>The problem is that the receiving system expects the data to be in <em>separate groups,</em> <em>grouped by the categories the rows belong to</em>. The expected message might look something like the below for category 10 (notice how all rows within the group are from category 10)</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7c7a1e91-697d-4883-9b88-15961b23e143" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns1:Group </span><span style="color: #FF0000; ">numberOfRows</span><span style="color: #0000FF; ">=&quot;5&quot;</span><span style="color: #FF0000; "> xmlns:ns1</span><span style="color: #0000FF; ">=&quot;http://Blah/Group&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0001</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0001, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0002</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0002, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0003</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0003, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0008</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0008, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0009</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Id</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0009, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ns1:Group</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
</span></div>
</pre>
</div>
<p>The problem is now that we need to find a efficient way of first <em>grouping the incoming flat file based message</em> and then to <em>debatch it using those groups. <strong>Our ultimate goal is to have separate messages that groups all rows that belongs to the same category and then send these messages to the receiving system</strong>. </em>How would you solve this? </p>
<p>I&#8217;ve seen loads of different solution involving orchestrations, databases etc, but the main problem they all had in common is that they&#8217;ve loaded up to much of the message in memory and finally hit an <em>OutOfMemoryException</em>.</p>
<h3>The solution</h3>
<p>The way to solve this is to use pure messaging as one of the new features in BizTalk 2006 is the new <a href="http://www.microsoft.com/technet/prodtechnol/biztalk/2006/evaluate/overview/default.mspx" target="_blank">large messages transformation engine</a>. </p>
<blockquote>
<p><b>Large message transformation.</b> In previous versions of BizTalk Server, mapping of documents always occurred in-memory. While in-memory mapping provides the best performance, it can quickly consume resources when large documents are mapped. In BizTalk Server 2006, large messages will be mapped by the new large message transformation engine, which buffers message data to the file system, keeping the memory consumption flat.</p>
</blockquote>
<p>So the idea is the to read the incoming flat file, use the <a href="FlatFileDisassembler " target="_blank">Flat File Disassembler</a> to transform the message to it&#8217;s XML representation (step 1,2 and in the figure below) and the to use XSLT to transform in to groups (step 4 and 5). We will then use the <a href="http://msdn.microsoft.com/en-us/library/aa561814.aspx" target="_blank">XML Disassembler</a> to split those groups into separate messages containing all the rows within a category (step 6 and 7).</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295groupingflow2-2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="98" alt="GroupingFlow2" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295groupingflow2-thumb.png" width="500" border="0" /></a></p>
<p>Step 1, 2 and 3 are <a href="http://msdn.microsoft.com/en-us/library/aa577898.aspx" target="_blank">straight forward</a> and pure configuration. Step 4 and 5 will require some custom XSLT and I&#8217;ll describe that in more detail in the section below.&#160; Step 6 and 7 will be discussed in the last section of the post.</p>
<h4>Grouping</h4>
<p>Let&#8217;s start by looking at a way to group the message. I will use some custom XSLT and a technique called the <a href="http://www.jenitennison.com/xslt/grouping/muenchian.html" target="_blank">Muenchian method</a>. A segment from the XML representation of the flat file message could look something like this. </p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b2723f04-42c2-403b-a87c-e187df037fab" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Rows </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">=&quot;http://Blah/Incoming_FF&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">=&quot;&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0001</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0001, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">=&quot;&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0002</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0002, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
&#8230;
[message cut for readability]</span></div>
</pre>
</div>
<p>The XSLT will use could look something like the below. It&#8217;s kind of straight forward and I&#8217;ve tried commenting the important parts of in the actual script. Basically it will use keys to fins the unique categories and then (again using keys) selecting those rows within the category to loop and write to a group.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cd3ebe5b-0cfd-4cb6-b2b6-4fa1601f567e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;?</span><span style="color: #FF00FF; ">xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;</span><span style="color: #0000FF; ">?&gt;</span><span style="color: #000000; ">

</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:stylesheet </span><span style="color: #FF0000; ">version</span><span style="color: #0000FF; ">=&quot;1.0&quot;</span><span style="color: #FF0000; ">
                xmlns:xsl</span><span style="color: #0000FF; ">=&quot;http://www.w3.org/1999/XSL/Transform&quot;</span><span style="color: #FF0000; ">
                xmlns:ns1</span><span style="color: #0000FF; ">=&quot;http://GroupAndDebatch.Schemas.Incoming_FF&quot;</span><span style="color: #FF0000; ">
                xmlns:ns2</span><span style="color: #0000FF; ">=&quot;http://GroupAndDebatch.Schemas.Grouped&quot;</span><span style="color: #FF0000; ">
                </span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #008000; ">&lt;!&#8211;</span><span style="color: #008000; ">Defining the key we&#8217;re gonna use</span><span style="color: #008000; ">&#8211;&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:key </span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">=&quot;rows-by-category&quot;</span><span style="color: #FF0000; "> match</span><span style="color: #0000FF; ">=&quot;Row&quot;</span><span style="color: #FF0000; "> use</span><span style="color: #0000FF; ">=&quot;Category&quot;</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/&gt;</span><span style="color: #000000; ">

    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:template </span><span style="color: #FF0000; ">match</span><span style="color: #0000FF; ">=&quot;/ns1:Rows&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns2:Groups</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">

        </span><span style="color: #008000; ">&lt;!&#8211;</span><span style="color: #008000; ">Looping the unique categories to get a group for</span><span style="color: #008000; ">&#8211;&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:for-each </span><span style="color: #FF0000; ">select</span><span style="color: #0000FF; ">=&quot;Row[count(. | key(&#8217;rows-by-category&#8217;, Category)[1]) = 1]&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">

            </span><span style="color: #008000; ">&lt;!&#8211;</span><span style="color: #008000; ">Creating a new group and set the numberOfRows</span><span style="color: #008000; ">&#8211;&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Group </span><span style="color: #FF0000; ">numberOfRows</span><span style="color: #0000FF; ">=&quot;{count(key(&#8217;rows-by-category&#8217;, Category))}&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">

            </span><span style="color: #008000; ">&lt;!&#8211;</span><span style="color: #008000; ">Loop all the rows within the specific category we&#8217;re on</span><span style="color: #008000; ">&#8211;&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:for-each </span><span style="color: #FF0000; ">select</span><span style="color: #0000FF; ">=&quot;key(&#8217;rows-by-category&#8217;, Category)&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:value-of </span><span style="color: #FF0000; ">select</span><span style="color: #0000FF; ">=&quot;ID&quot;</span><span style="color: #0000FF; ">/&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:value-of </span><span style="color: #FF0000; ">select</span><span style="color: #0000FF; ">=&quot;Text&quot;</span><span style="color: #0000FF; ">/&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">xsl:value-of </span><span style="color: #FF0000; ">select</span><span style="color: #0000FF; ">=&quot;Category&quot;</span><span style="color: #0000FF; ">/&gt;</span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
                </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">xsl:for-each</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Group</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">xsl:for-each</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ns2:Groups</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">xsl:template</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">

</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">xsl:stylesheet</span><span style="color: #0000FF; ">&gt;</span></div>
</pre>
</div>
<blockquote>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295note-2.gif"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="18" alt="note" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295note-thumb.gif" width="18" align="left" border="0" /></a>You have found all the <a href="http://msdn.microsoft.com/en-us/library/aa302298.aspx" target="_blank">XSLT and XML related features</a> in Visual Studio - right?</p>
</blockquote>
<p>Ok, so the above XSLT will give us a XML structure that looks some like this.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:bac0c3cc-f8ba-4ade-8c99-7e593803976d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;?</span><span style="color: #FF00FF; ">xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;</span><span style="color: #0000FF; ">?&gt;</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns2:Groups </span><span style="color: #FF0000; ">xmlns:ns2</span><span style="color: #0000FF; ">=&quot;http://Blah/Groups&quot;</span><span style="color: #FF0000; "> xmlns:ns1</span><span style="color: #0000FF; ">=&quot;http://Blah/Group&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns1:Group </span><span style="color: #FF0000; ">numberOfRows</span><span style="color: #0000FF; ">=&quot;5&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0001</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0001, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0002</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0002, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0003</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0003, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0008</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0008, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0009</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0009, category 10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">10</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ns1:Group</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns1:Group </span><span style="color: #FF0000; ">numberOfRows</span><span style="color: #0000FF; ">=&quot;4&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">0004</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ID</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test row, id 0004, category 20</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Text</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">20</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Category</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Row</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
&#8230;
[message cut for readability]</span></div>
</pre>
</div>
<p><strong>Finally! This we can debatch!</strong></p>
<h4>Debatching</h4>
<p>Debatch the <em>Groups</em> message above is also rather straight forward and I won&#8217;t spend much time on in this post. The best way to learn more about it is to have a look ate the <a href="http://msdn.microsoft.com/en-us/library/ms966332.aspx" target="_blank">EnvelopeProcessing sample</a> in the BizTalk SDK.</p>
<p><strong>And the end result of the debatching are single messages within a unique category, just as the receiving system expects! Problem solved.</strong></p>
<h3>Issue #1 - slow transformations</h3>
<p>The first time I&#8217;ve put a solution like this in test and started testing with some real sized messages (&gt; 1 MB) I really panicked, the mapping took forever. And I really mean forever, I sat there waiting for 2-3 hours (!) for a single file getting transformed. When I had tested the same XML based file in Visual Studio the transformation took about 10 seconds so I knew that wasn&#8217;t it. With some digging <a href="http://technet.microsoft.com/en-us/library/aa560481.aspx" target="_blank">here</a> I found the <em>TransformThreshold</em> parameter. </p>
<p><em>TransformThreshold</em> decides how big a message can be in memory before BizTalk start buffering it to disk. The default value is 1 MB and one really has to be careful when changing this. Make sure you thought hard about your solution and situation before changing the value - how much traffic do you receive and how much of that can you afford reading in to memory?</p>
<p>In my case I received a couple of big files spread out over a night so setting parameter with a large amount wasn&#8217;t really a problem and that really solved the problem. The mapping finished in below 10 minutes as I now allow a much bigger message to be read into memory and executed in memory before switching over to the large message transformation engine and start buffering to disk (which is always much slower).</p>
<h3>Problem #2 - forced to temp storage</h3>
<p>Looking at the model of the data flow again you probably see that I&#8217;m using the XML Disassembler to split the grouped files (step 5 to step 6). </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295groupingflow3-2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="146" alt="GroupingFlow3" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterefficientgroupingandsplittingofbigfiles-8295groupingflow3-thumb.png" width="500" border="0" /></a> </p>
<p>The only way I&#8217;ve found this to work is actually to write the Grouped XML message to file and the to read that file in to BizTalk again and in that receive pipeline debatch the message. Not the most elegant solution, but there really isn&#8217;t a another out-of-the-box way of debatching messages (the XML Assembler can&#8217;t do it) and I don&#8217;t want to use an orchestration to execute the a pipeline as I want to keep the solution pure messaging for simplicity and performance reasons.</p>
<h3>Finishing up</h3>
<p>Have you solved similar cases differently? I&#8217;d be very interested in your experience! I also have a sample solution of this - just send me an <a href="email:richard.hallgren@gmail.com" target="_blank">email</a> and make sure you&#8217;ll get it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/efficient-grouping-and-debatching-of-big-files-using-biztalk-2006/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Running MSBuild scripts from Visual Studio</title>
		<link>http://www.richardhallgren.com/running-msbuild-scripts-from-visual-studio/</link>
		<comments>http://www.richardhallgren.com/running-msbuild-scripts-from-visual-studio/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 09:04:22 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[MSBuild]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/running-msbuild-scripts-from-visual-studio/</guid>
		<description><![CDATA[It seems like there more build script one writes, the more often one wants to run them and it&#8217;s always a bit annoying (and time consuming) having to leave Visual Studio and start MSBuild from the command line. Brennan Stehling has a cool solution to that problem here were he sets up MSBuild as an [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterrunningmsbuildscriptsfromvisualstudio-9bb0msbuild2-2.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 4px 15px 15px; border-left: 0px; border-bottom: 0px" height="242" alt="MSBuild2" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterrunningmsbuildscriptsfromvisualstudio-9bb0msbuild2-thumb.png" width="244" align="right" border="0" /></a>It seems like there more build script one writes, the more often one wants to run them and it&#8217;s always a bit annoying (and time consuming) having to leave Visual Studio and start MSBuild from the command line. Brennan Stehling has a cool solution to that problem <a href="http://brennan.offwhite.net/blog/2007/05/31/running-msbuild-from-visual-studio/">here</a> were he sets up MSBuild as an external tool and runs it.</p>
<p>One problem for us was the we had our solution files in one place on the file system and our build files in a totally different place. The solution was to add the build file for the current solution as a <a href="http://msdn.microsoft.com/en-us/library/haytww03(VS.80).aspx">Solution Folder</a> (as shown in the figure below) and then set MSBuild to use $(ItemDir) as its Initial Directory. That will kick of MSBuild from the directory that the current selected Solution Folder points to and in our case that&#8217;s were the XXX.Build.Article.proj file exists.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterrunningmsbuildscriptsfromvisualstudio-9bb0msbuild-6.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="321" alt="MSBuild" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterrunningmsbuildscriptsfromvisualstudio-9bb0msbuild-thumb-2.png" width="504" border="0" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/running-msbuild-scripts-from-visual-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Looking forward to stackoverflow.com</title>
		<link>http://www.richardhallgren.com/looking-forward-to-stackoverflowcom/</link>
		<comments>http://www.richardhallgren.com/looking-forward-to-stackoverflowcom/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 06:52:12 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Community]]></category>

		<category><![CDATA[Podcast]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/looking-forward-to-stackoverflowcom/</guid>
		<description><![CDATA[I&#8217;m really looking forward to the release of stackoverflow.com - have you heard about it? If not it&#8217;s a collaboration between Joel Spolsky and Jeff Atwood. Joel and Jeff are of course the two blogger behind the popular Joel on Software and Coding Horror blogs. 
Joel is also one of the founders of the FogCreek [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterlookingforwardtostackoverflow.com-7cb8stackoverflow-logo-250-2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 20px 20px; border-right-width: 0px" height="67" alt="stackoverflow-logo-250" src="http://www.richardhallgren.com/wp-content/uploads/2008/07/windowslivewriterlookingforwardtostackoverflow.com-7cb8stackoverflow-logo-250-thumb.png" width="240" align="right" border="0" /></a>I&#8217;m really looking forward to the release of s<a href="http://stackoverflow.com/" target="_blank">tackoverflow.com</a> - have you heard about it? If not it&#8217;s a collaboration between <a href="http://www.joelonsoftware.com/AboutMe.html">Joel Spolsky</a> and <a href="http://www.codinghorror.com/blog/archives/000021.html">Jeff Atwood</a>. Joel and Jeff are of course the two blogger behind the popular <a href="http://www.joelonsoftware.com/" target="_blank">Joel on Software</a> and <a href="http://www.codinghorror.com/blog/">Coding Horror</a> blogs. </p>
<p>Joel is also one of the founders of the <a href="http://fogcreek.com/">FogCreek Software</a> company. FogCreek has a couple of different products but the most known is probably <a href="http://fogcreek.com/FogBugz/">FogBugz</a> which is a really cool project management/bug tracking/wiki/support tool for software development and management. At first it might not look like a very impressing tool but have a look at <a href="http://www.joelonsoftware.com/items/2007/10/24austindemo.html">this presentation</a> by Joel and I think you&#8217;ll start thinking different (I know we did and we&#8217;re now using it for both planing and managing big integrations projects).</p>
<p>Anyway, if you missed the story behind stackoverflow have a look <a href="http://blog.stackoverflow.com/" target="_blank">here</a> and don&#8217;t miss the <a href="http://blog.stackoverflow.com/index.php?feed=podcast">podcasts</a> that Joel and Jeff record, some of them are really cool. I know I&#8217;ve learnt a lot by just listening in to their conversations.</p>
<p>We not have quite a few online BizTalk communities such as <a href="http://forums.microsoft.com/msdn/default.aspx?ForumGroupID=398&amp;SiteID=1">the Microsoft forums</a>, <a href="http://groups.google.com/group/microsoft.public.biztalk.general/topics">Google Groups</a>, <a href="http://www.biztalkgurus.com/forums/default.aspx">BizTalk Gurus</a>, <a href="http://www.facebook.com/">facebook</a> (search for BizTalk related groups) and at <a href="https://www.linkedin.com/home">LinkedIn</a> (a couple of open BizTalk related groups) - is there room for another one at stackoverflow? Do we need one?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/looking-forward-to-stackoverflowcom/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Removing XML namespaces - revisit</title>
		<link>http://www.richardhallgren.com/removing-xml-namespaces-revisit/</link>
		<comments>http://www.richardhallgren.com/removing-xml-namespaces-revisit/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 07:25:33 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[R2]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/removing-xml-namespaces-revisit/</guid>
		<description><![CDATA[I have a old post on removing XML namespace from outgoing messages using XSLT in a map on the send port. Removing XML namespace is usually a late requirement that shows up during integration tests with for example legacy systems that has problems reading XML and only finds XML namespaces messy and confusing and wants [...]]]></description>
			<content:encoded><![CDATA[<p>I have a <a href="http://www.richardhallgren.com/removing-namespace-from-outgoing-messages/" target="_blank">old post on removing XML namespace</a> from outgoing messages using XSLT in a map on the send port. Removing XML namespace is usually a late requirement that shows up during integration tests with for example legacy systems that has problems reading XML and only finds XML namespaces messy and confusing and wants it removed. </p>
<p>The post recently got commented by <a href="http://codebetter.com/blogs/jeff.lynch/" target="_blank">Jeff Lynch</a> (one of the <a href="http://codebetter.com/" target="_blank">codebetter.com</a> bloggers) asking me why I just didn&#8217;t create a schema without any XML namespace in it to represent the outgoing schema (see figure below) and then map to that in the send port.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/06/windowslivewriterremovingxmlnamespacesrevisit-834dremoving-xml-namespaces-revisit-2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="242" alt="Removing XML namespaces - revisit" src="http://www.richardhallgren.com/wp-content/uploads/2008/06/windowslivewriterremovingxmlnamespacesrevisit-834dremoving-xml-namespaces-revisit-thumb.png" width="500" border="0" /></a> </p>
<p>Say for example that we have incoming messages like the one below with namespaces.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:baf9dd94-4deb-4a9a-a3b2-bf9d6a0ef7ab" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">ns0:BlahRoot </span><span style="color: #FF0000; ">xmlns:ns0</span><span style="color: #0000FF; ">=&quot;http://Sample.BlahIncomingSchema&quot;</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">BlahNode</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test Value</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">BlahNode</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">ns0:BlahRoot</span><span style="color: #0000FF; ">&gt;</span></div>
</pre>
</div>
<p>We&#8217;ve then defined a schema without namespace and map to that and get the following result.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e9433bc0-3486-400f-9d61-3bfc529ef283" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">BlahRoot</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
  </span><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">BlahNode</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">Test Value</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">BlahNode</span><span style="color: #0000FF; ">&gt;</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">BlahRoot</span><span style="color: #0000FF; ">&gt;</span></div>
</pre>
</div>
<p>This method is of course much cleaner then any previous and it&#8217;s also more conceptually correct as the schema actually represents the contact between BizTalk and the receiving system (the contract is a message without namespace in it, <strong>not one with that we then remove</strong>).</p>
<p>The only problem with this kind of approach is that as BizTalk recognized the message type using a combination between root node and XML namespace we can&#8217;t have another schema with the <em>BlahRoot</em> root node without a defined XML namespace. Even if those two schemas would look totally different in structure and be two different message types BizTalk would be able to see the difference (to BizTalk they both be <em>#BlahRoot</em> message types).</p>
<p>Thanks Jeff for pointing this out to me. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/removing-xml-namespaces-revisit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Does BizTalk have man-boobs?</title>
		<link>http://www.richardhallgren.com/does-biztalk-have-man-bobs/</link>
		<comments>http://www.richardhallgren.com/does-biztalk-have-man-bobs/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 07:14:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[R2]]></category>

		<category><![CDATA[Webcast]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/does-biztalk-have-man-bobs/</guid>
		<description><![CDATA[I&#8217;ve just finished watching this webcast from QCon 2008 with Martin Fowler and Jim Webber. It&#8217;s basically their view on how integration middleware is used today and how we plan and implement our SOA and ESB project. 
Their main point is that we use much to bloated middleware (BizTalk is mentioned as an example here) [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just finished watching <a href="http://www.infoq.com/presentations/soa-without-esb" target="_blank">this webcast</a> from <a href="http://qcon.infoq.com/sanfrancisco-2008/conference/" target="_blank">QCon 2008</a> with <a href="http://martinfowler.com/" target="_blank">Martin Fowler</a> and <a href="http://jim.webber.name/" target="_blank">Jim Webber</a>. It&#8217;s basically their view on how integration middleware is used today and how we plan and implement our SOA and ESB project. </p>
<p>Their main point is that we use much to bloated middleware (BizTalk is mentioned as an example here) and that we should have a more agile approach to implement SOA and ESBs. They&#8217;ve used all the agile ideas (testing, isolated testable functionality, deliver small and often, continuous builds etc, etc) and applied them to integration - fair enough. I totally agree that trying to convert your complete enterprise architecture into a SOA architecture is a guaranteed failure. This is also <a href="http://www.microsoft.com/biztalk/solutions/soa/overview.mspx#EZB" target="_blank">something we heard for a while now from others</a> as well.</p>
<p>I do also agree that BizTalk is a huge platform and that it isn&#8217;t perfect in all aspects. IMHO it does however give us some important advantages compared to a custom coded message bus and services. I&#8217;ll try and list a few of them below.</p>
<ol>
<li><strong>Fixed architecture</strong>       <br />We don&#8217;t have invent the wheel every time. BizTalk is a product with an <a href="http://msdn.microsoft.com/en-us/library/aa561521.aspx" target="_blank">architecture</a> that one have to learn and use. There are times when this is a pain (did I hear low latency and BizTalk persistence points?) but it&#8217;s also a huge kick start to all projects once you learnt it. Once you figured out how you use the products you&#8217;ll actually have something up and running in no time.       </p>
<p>Isn&#8217;t an early delivery that we can test something good? I&#8217;m sure I can deliver a BizTalk based integration faster that some can using custom code when starting from scratch.       <br />&#160; </li>
<li><strong>Drag-and-drop</strong>       <br />There is a learning curve to BizTalk and all it&#8217;s tools but once one gotten over this one can move really fast, even without a deep understanding of .NET and software development (there are of course both pros and cons to this). I&#8217;ve seen projects with 50+ integration processes (to me that&#8217;s a big, complex project) where we actually used people fresh out of school, spent two weeks to teach them basic BizTalk and had them deliver critical parts of the projects. I&#8217;d like to see that happen custom coded ESB project with thousands lines of code &#8230;
<p>You probably get a nice design and implementation if you can hire 10 top developers and a couple of architects, but that isn&#8217;t always possible.       <br />&#160; </li>
<li><strong>Tools        <br /></strong>Does a custom code, lean approach, really scale in this scenario? Do you take the time to pause and build that management and configuration tool that you don&#8217;t get with a custom code project? I don&#8217;t say that we got the perfect view and control of our processes and messages in BizTalk but at least we got <strong>some</strong> control. At least I got the <a href="http://technet.microsoft.com/en-us/library/aa578089.aspx" target="_blank">BizTalk Administration Console</a> to let me see how my different application are doing, what messages and process etc that got suspended. At least I got the BAM framework where I can configure a tracking and monitoring in no time (usually &#8230;) etc, etc.&#160; <br />&#160; </li>
<li><strong>It works        <br /></strong>Say your implementing a process that receives purchase orders and that these orders might contain orders for a couple of millions dollars. Do you want to be developer that tells you boss that you think you might have lost a message due to a exception in your custom code? Of course you have 90% test coverage and continuous integration but you never tested for this exception case &#8230; I don&#8217;t want to be that developer/architect. </li>
</ol>
<p>I don&#8217;t say don&#8217;t test. I&#8217;m very pro testing and I really feel that agile is the right approach. I&#8217;m just saying I need something tested and safe to build this super critical solutions on. Something that I know works and that I can be really productive on and start solving business cases from minute one.</p>
<p>What do you think? Does BizTalk have man-bobs and is that only a bad thing? And does Martin Fowler really have leather pants on?    </p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/does-biztalk-have-man-bobs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Speaking at KNUG - Karlstad .NET User Group</title>
		<link>http://www.richardhallgren.com/speaking-at-knug-karlstad-net-user-group/</link>
		<comments>http://www.richardhallgren.com/speaking-at-knug-karlstad-net-user-group/#comments</comments>
		<pubDate>Fri, 09 May 2008 14:05:53 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[Presentation]]></category>

		<category><![CDATA[R2]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/speaking-at-knug-karlstad-net-user-group/</guid>
		<description><![CDATA[Yesterday I presented the MasterData Management using BizTalk 2006 R2 talk (I&#8217;ll soon have a post out with the presentation in English) I recently held at Developer Summit at the local .NET user group in Karlstad (KNUG). 
KNUG is a new .NET user group that I actually helped start a couple of months ago. This [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I presented the <a href="http://www.richardhallgren.com/talking-at-developer-summit-on-masterdata-management-using-biztalk-2006/" target="_blank">MasterData Management using BizTalk 2006 R2 talk</a> (I&#8217;ll soon have a post out with the presentation in English) I recently held at Developer Summit at the local .NET user group in Karlstad (<a href="http://www.compare.se/index.asp?id=6221">KNUG</a>). </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/05/windowslivewriterspeakingatknugkarlstad.netusergroup-e257janolof-on-how-to-be-cool.jpg"><img style="border-right: 0px; border-top: 0px; margin: 0px 15px 15px; border-left: 0px; border-bottom: 0px" height="243" alt="Janolof on how to be cool" src="http://www.richardhallgren.com/wp-content/uploads/2008/05/windowslivewriterspeakingatknugkarlstad.netusergroup-e257janolof-on-how-to-be-cool-thumb.jpg" width="237" align="right" border="0" /></a>KNUG is a new .NET user group that I actually helped start a couple of months ago. This meeting was the second meeting for the group. The meeting was attended by about 20 persons and we had two presentations on the agenda. Besides my own Thomas Heder showed the group some <a href="http://en.wikipedia.org/wiki/Language_Integrated_Query" target="_blank">LINQ</a> and how he and his colleagues uses <a href="http://www.linqpad.net/" target="_blank">LINQPad</a> to develop and test there queries.</p>
<p>We also discussed future subjects, possible speakers and moving information on the group over to a <a href="http://communityserver.com/" target="_blank">Community Server</a> driven site. </p>
<p>Does anyone have any experience on Community Server and how the feature set matches those need for running a user group (managing users, blogs, email lists, calendar etc)? </p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/speaking-at-knug-karlstad-net-user-group/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using BAM for latency tracking in a BizTalk request response scenario</title>
		<link>http://www.richardhallgren.com/using-bam-for-latency-tracking-in-a-biztalk-request-response-scenario/</link>
		<comments>http://www.richardhallgren.com/using-bam-for-latency-tracking-in-a-biztalk-request-response-scenario/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 13:35:15 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
		
		<category><![CDATA[BAM]]></category>

		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/using-bam-for-latency-tracking-in-a-biztalk-request-response-scenario/</guid>
		<description><![CDATA[This post will try and explain how BAM tracking can be used in SOAP based request response scenario in BizTalk 2006. It important to notice that some of the issues discussed in the post are specific to the SOAP adapter and are non-issues if the scenario would for example use the the WCF adapter or [...]]]></description>
			<content:encoded><![CDATA[<p>This post will try and explain how BAM tracking can be used in SOAP based request response scenario in BizTalk 2006. It important to notice that some of the issues discussed in the post are specific to the SOAP adapter and are non-issues if the scenario would for example use the the WCF adapter or similar.</p>
<h4>Describing the scenario</h4>
<p>In this case we have a SOAP receive port that receives a request and returns a response. The request is routed to a orchestration that calls three different send ports. These ports then sends new requests to back-end systems and returns responses (communication with back-ends systems are also SOAP based). The three responses are used to build up the final response that is then returned to original receive port as a final response.</p>
<p>Our goal is to track the duration between the request and response on each of the ports. The idea is also to find a solution and tracking model that doesn&#8217;t have to change if we add or remove ports or add similar processes to track.</p>
<h4><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bscenario-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="429" alt="scenario" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bscenario-thumb.jpg" width="520" border="0" /></a> </h4>
<h4>Defining and deploying the tracking model</h4>
<p>We&#8217;ll start by defining our tracking model in Excel. Our activity contains of the following items: </p>
<ul>
<li><b>InterchangeId</b> (data item)       <br />As we won&#8217;t correlate all the tracking point into one single row (that would break the goal of having one model for all processes, the model would then have to be specific for one process and it&#8217;s specific ports) the interchange id will then tell us what different rows belong together and that describes one process. </li>
<li><b>ReceivePortName</b> (data item)       <br />The name of the receive port. </li>
<li><b>Request</b> (milestone item)       <br />The time the request was either sent or received (depending on if we track a port that received/sent the request using a receive port or send port). </li>
<li><b>Response</b> (milestone item)       <br />The time the response was either sent or received (depending on if we track a port that received/sent it&#8217;s response on a receive port or send port). </li>
<li><b>SendPortName</b> (data item)       <br />The name of the send port. </li>
</ul>
<p>After we described the model it&#8217;s time to export it to an XML representation and then to use the <a href="http://technet.microsoft.com/en-us/library/aa547898.aspx" target="_blank">BM tool</a> to deploy it and generate the BAM database infrastructure. You&#8217;ll find some nice info on this <a href="http://msdn2.microsoft.com/en-us/library/aa558802.aspx" target="_blank">here</a>.</p>
<h4>Using the Tracking Profile Editor to bind the model</h4>
<p>Next step is to bind the model to the implementation using the <a href="http://msdn2.microsoft.com/en-us/library/ms946851.aspx" target="_blank">Tracking Profile Editor</a>. The figure below shows the different properties that were used. Notice that none of the items was bound to the actual orchestration context. All properties are general properties that we track <b>on the ports</b>.<b> </b>This is important as that gives us the possibility to just add and remove ports to change the tracking. </p>
<p><b><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-using-continuation-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="391" alt="tracking profile using continuation" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-using-continuation-thumb.jpg" width="500" border="0" /></a> </b></p>
<p><b></b></p>
<p>The next figure shows how the tracking of the request milestone event actually happens on either the RP1 port or on any of the three different send ports! If we developed a new process using other ports we could just add it here, no new model required. </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-configure-ports-2-4.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="423" alt="tracking profile configure ports 2" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-configure-ports-2-thumb-1.jpg" width="500" border="0" /></a> </p>
<h4>What about the continuation then?</h4>
<p>Our final problem is that unless we somehow correlate our request tracking point with our receive tracking point the receive we&#8217;ll end up with each tracking point spread over several different rows. In the example below I&#8217;ve marked the request for the RP01 port and the response event on the same port.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bbam-portal-split-results-4.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="158" alt="bam portal split results" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bbam-portal-split-results-thumb-1.jpg" width="520" border="0" /></a> </p>
<p>The reason for this is of course that BAM doesn&#8217;t have a context for the two tracking points and doesn&#8217;t know that actually belongs together. This differs from tracking in a orchestration were we always are in a context (the context of the orchestration), it&#8217;s then easy for BAM to understand that we like to view all the tracking point as one row &#8211; when tracking on ports it&#8217;s different. Continuation helps us tell BAM that we like have a context and correlate these two points. </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-using-continuation-2-6.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="381" alt="tracking profile using continuation 2" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0btracking-profile-using-continuation-2-thumb-2.jpg" width="500" border="0" /></a> </p>
<p>In our case ServiceID is the prefect candidate for correlating the two points. A request and a response will have the same service id. In an other situation we could just as well have used a value from inside the message (say for example an invoice id).</p>
<p><strong>The result is one single row for the request response for each port</strong>. So in our case a complete process (a complete interchange) is shown on four rows (one row for each of the ports). In the example below the first rows shows us the complete duration (and the other tracking data) between the request response to the client. The other rows show the duration for the send ports communication with the back-ends systems.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bbam-portal-complete-results-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="118" alt="bam portal complete results" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bbam-portal-complete-results-thumb.jpg" width="520" border="0" /></a></p>
<p>This model might not be optimal in an other scenario where your process are more fixed and you can then create a tracking model that is more specific to you actual process. But this solution meets our design goal as we&#8217;re now able to just add and remove port using the tracking profiler to track new port in completely new processes without having to go back and change the tracking model.</p>
<blockquote><p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bnote-2.gif"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 5px; border-right-width: 0px" height="14" alt="note" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterusingbamforlatencytrackinginabiztalkrequ-9c0bnote-thumb.gif" width="14" border="0" /></a>&#160; NOTE: When configuring BAM to track a port the <em><a href="http://msdn2.microsoft.com/en-us/library/aa561650.aspx" target="_blank">MessageType</a></em> is actually promoted. This causes some problems in combination with the SOAP based ports that have been published using the Web Services Publishing Wizard. Saravana writes about this <a href="http://www.digitaldeposit.net/blog/2007/08/soap-adapter-and-biztalk-web-publishing.html">here</a> and all his articles on this subject is a must read when working with SOAP ports. The problem however comes down to that the Web Services Publishing Wizard generates code that puts the wrong <em>DocumentSpecName </em>in the message context and that causes the <em>XmlDisassembler</em> to fail (it tricks the <em>XmlDisassembler</em> to look for a <em>MessageType</em> that doesn&#8217;t exists). </p>
<p>This usually isn&#8217;t a problem (unless you like to use a map on a port) but as BAM will force the port to promote the <em>MessageType</em> based on the <em>DocumentSpecName </em>we&#8217;ll have to fix this. Saravana has two solutions to the problem and I find the one that replaces the <em>DocumentSpecName</em> with a null value and lets the <em>XmlDisassembler</em> find the <em>MessageType</em> to work well.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/using-bam-for-latency-tracking-in-a-biztalk-request-response-scenario/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Speaking at Developer Summit on Masterdata Management using BizTalk 2006</title>
		<link>http://www.richardhallgren.com/talking-at-developer-summit-on-masterdata-management-using-biztalk-2006/</link>
		<comments>http://www.richardhallgren.com/talking-at-developer-summit-on-masterdata-management-using-biztalk-2006/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 20:33:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[Presentation]]></category>

		<category><![CDATA[R2]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/talking-at-developer-summit-on-masterdata-management-using-biztalk-2006/</guid>
		<description><![CDATA[I recently spoke at the leading developer conference here in Sweden called Developer Summit. The talk was called Masterdata Management using BizTalk 2006. The slides can be found here.
I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like David Chappell, Jim Webber, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently spoke at the leading developer conference here in Sweden called <a href="http://www.expertzone.se/dev08/" target="_blank">Developer Summit</a>. The talk was called <em>Masterdata Management using BizTalk 2006</em>. The slides can be found <a href="http://www.richardhallgren.com/blogfiles/MasterData%20Management%20-%20Developer%20Summit%203.0.ppt" target="_blank">here</a>.</p>
<p>I can really recommend Developer Summit as a conference. Everything is super well organized and having the opportunity to listen to celebrities like <a href="http://www.davidchappell.com/blog/" target="_blank">David Chappell</a>, <a href="http://jim.webber.name/" target="_blank">Jim Webber</a>, <a href="http://dannorth.net/" target="_blank">Dan North</a> and <a href="http://blogs.thinktecture.com/cweyer/" target="_blank">Christian Weyer</a>&#160;<strong>in Sweden</strong> is really great! </p>
<p>This year I also liked the mix of presentation as some where more general presentation as for example&#160; Benjamin Ling who&#8217;s the director of platform at Facebook and who gave an insight to how the platform is managed and developed. I also really enjoyed (besides the obvious ones as for example Christian Weyer&#8217;s WCF talk) Frans H&#228;nel&#8217;s talk on the history and architecture behind a major price comparison site called <a href="http://prisjakt.nu/" target="_blank">prisjakt.nu</a> - very interesting and a great technical mix in otherwise Microsoft focused conference.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/talking-at-developer-summit-on-masterdata-management-using-biztalk-2006/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Writing BizTalk context properties to a message from a WCF service using behaviors</title>
		<link>http://www.richardhallgren.com/writing-biztalk-context-properties-to-a-message-from-a-wcf-service-using-behaviors/</link>
		<comments>http://www.richardhallgren.com/writing-biztalk-context-properties-to-a-message-from-a-wcf-service-using-behaviors/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 17:43:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[BizTalk 2006]]></category>

		<category><![CDATA[R2]]></category>

		<category><![CDATA[Sample code]]></category>

		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/writing-biztalk-context-properties-to-a-message-from-a-wcf-service-using-behaviors/</guid>
		<description><![CDATA[The new WCF adapter in BizTalk 2006 R2 offers a lot of new possibilities. One of those is to write data to the BizTalk Message context properties directly from an exposed WCF Service. A practical use of this technic could be to write the username from the Windows credentials of the calling client into the [...]]]></description>
			<content:encoded><![CDATA[<p>The new WCF adapter in BizTalk 2006 R2 offers a lot of new possibilities. One of those is to write data to the BizTalk Message context properties directly from an exposed WCF Service. A practical use of this technic could be to write the username from the Windows credentials of the calling client into the context of the BizTalk message. This could be useful as this information is encrypted in messages that are received via the WCF adapter and isn&#8217;t possible to read when inside BizTalk. I&#8217;ll try and demonstrate the technique in this post.</p>
<p>If you have used the SOAP adapter before you might know that all you had to do was to turn on Windows based security for the exposed SOAP service and the username was automatically promoted to the context of the incoming BizTalk message. That username could then be used for routing, tracking which user called the service or using the value in plain text when communicating further to other connected systems. However using the WCF adapter this is not true anymore - when using the new <a href="http://msdn2.microsoft.com/en-us/library/ms789036.aspx" target="_blank">WCF Message Security model</a> the username and password is encrypted in the message and once the message is received by BizTalk it&#8217;s to late to read it. Basically we have to read the username in the actual service and write it into our own context property (that doesn&#8217;t get encrypted).</p>
<p>One way of achieving this is to read the username in the service and then to add it to the WCF Message Headers. All WCF message headers will by default be written to a the BizTalk Message context property called <a href="http://msdn2.microsoft.com/en-us/library/bb259987.aspx" target="_blank">InboundHeaders</a> (in the <em>http://schemas.microsoft.com/BizTalk/2006/1/Adapters/WCF-properties</em> namespace). First we&#8217;ll create an EndpointBehavior that will use a MessageInspector to add the username to the message header.&#160; Finally we create BehaviorExtensionElement so we can use a WCF Custom Binding in BizTalk and configure it to add our new behavior.</p>
<h1>Creating the new EndpointBehavior</h1>
<p>To create the configurable behavior we&#8217;ll need the three classes we mentioned above.</p>
<ol>
<li>A class that implements the <a href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.aspx" target="_blank">IDispatchMessageInspector</a> interface to handle to reading and writing to the actual message. </li>
<li>A class that implements the <a href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.description.iendpointbehavior.aspx" target="_blank">IEndpointBehavior</a> interface to define what kind of endpoint we&#8217;re creating and what it should do. </li>
<li>A class that implements the <a href="http://msdn2.microsoft.com/en-us/library/system.servicemodel.configuration.behaviorextensionelement.aspx" target="_blank">BehaviorExtensionElement</a> abstract class to&#160; create the behavior and make it configurable. </li>
</ol>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:30a38abf-8115-47a6-9437-40a4eed2f89b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.Collections.Generic;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.Text;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.ServiceModel;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.ServiceModel.Channels;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.ServiceModel.Dispatcher;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.ServiceModel.Description;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; "> System.ServiceModel.Configuration;

</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; "> CustomWCFProperties.Behavior
{
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;summary&gt;</span><span style="color: #008000; ">
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> PromoteUserNameMessageInspector implements IDispatchMessageInspector and adds the name from the WindowsIdentity to a WCF header called WindowsUserName in the </span><span style="color: #008000; text-decoration: underline; ">http://CustomWCFProperties.Schema</span><span style="color: #008000; "> namespace. BeforeSendReply only returns as we&#8217;re not interested in handling the response.
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;/summary&gt;</span><span style="color: #808080; ">
</span><span style="color: #000000; ">    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> PromoteUserNameMessageInspector : IDispatchMessageInspector
    {
        </span><span style="color: #0000FF; ">#region</span><span style="color: #000000; "> IDispatchMessageInspector Members</span><span style="color: #000000; ">

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">object</span><span style="color: #000000; "> AfterReceiveRequest(</span><span style="color: #0000FF; ">ref</span><span style="color: #000000; "> System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            </span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> windowsUserName </span><span style="color: #000000; ">=</span><span style="color: #000000; "> ServiceSecurityContext.Current.WindowsIdentity.Name;
            request.Headers.Add(MessageHeader.CreateHeader(</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">WindowsUserName</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">, </span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">http://CustomWCFProperties.Schema</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">, windowsUserName));
            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;
        }

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> BeforeSendReply(</span><span style="color: #0000FF; ">ref</span><span style="color: #000000; "> Message reply, </span><span style="color: #0000FF; ">object</span><span style="color: #000000; "> correlationState)
        {
            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;
        }

        </span><span style="color: #0000FF; ">#endregion</span><span style="color: #000000; ">
    }

    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;summary&gt;</span><span style="color: #008000; ">
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> PromoteUserNameBehavior implements IEndpointBehavior and adds a message inspector to the dispatch behavior. Doesn&#8217;t use any binding parameters, doesn&#8217;t validate any configuration etc and can&#8217;t be used in a client (only in a service).
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;/summary&gt;</span><span style="color: #808080; ">
</span><span style="color: #000000; ">    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> PromoteUserNameBehavior : IEndpointBehavior
    {
        </span><span style="color: #0000FF; ">#region</span><span style="color: #000000; "> IEndpointBehavior Members</span><span style="color: #000000; ">

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;
        }

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            </span><span style="color: #0000FF; ">throw</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> Exception(</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">The method or operation is not implemented.</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">);
        }

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> PromoteUserNameMessageInspector());
        }

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> Validate(ServiceEndpoint endpoint)
        {
            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;
        }

        </span><span style="color: #0000FF; ">#endregion</span><span style="color: #000000; ">
    }

    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;summary&gt;</span><span style="color: #008000; ">
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> Defines the behavior.
    </span><span style="color: #808080; ">///</span><span style="color: #008000; "> </span><span style="color: #808080; ">&lt;/summary&gt;</span><span style="color: #808080; ">
</span><span style="color: #000000; ">    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> PromoteUserNameBehaviorElement : BehaviorExtensionElement
    {
        </span><span style="color: #0000FF; ">protected</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">override</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">object</span><span style="color: #000000; "> CreateBehavior()
        {
            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> PromoteUserNameBehavior();
        }

        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">override</span><span style="color: #000000; "> Type BehaviorType
        {
            </span><span style="color: #0000FF; ">get</span><span style="color: #000000; "> { </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">typeof</span><span style="color: #000000; ">(PromoteUserNameBehavior); }
        }
    }
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</p>
<p>Finally we have to sign the assembly using a strong key and add it to the GAC.</p>
<h1>Configure the machine.config</h1>
<p>As we need BizTalk and the WCF adapter to pick up the need behavior and make it possible to configure our receive port we need to to add the behavior element to the <a href="http://msdn2.microsoft.com/en-us/library/ms229697(VS.71).aspx" target="_blank">machine.config</a>. The easiest way of doing this is to use the new <a href="http://msdn2.microsoft.com/en-us/library/ms732009.aspx" target="_blank">WCF Service Configuration Editor tool</a> and point to the machine.config file.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4promoteusernamebehavior-gac-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="343" alt="PromoteUserNameBehavior GAC" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4promoteusernamebehavior-gac-thumb.jpg" width="500" border="0" /></a></p>
<p>After the dll been added and the machine.config file has been saved the the line below should have been added to the <a href="http://msdn2.microsoft.com/en-us/library/aa734726.aspx" target="_blank">&lt;behaviorExtensions&gt; element</a> (that is if you use the same strong name key as in the sample project I&#8217;ve linked here).</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:6bc92cdd-9ed1-4dfc-954f-4e60721cfaae" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">add </span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">=&quot;addCustomWCFProperties&quot;</span><span style="color: #FF0000; "> type</span><span style="color: #0000FF; ">=&quot;CustomWCFProperties.Behavior.PromoteUserNameBehaviorElement, AddCustomWCFPropertiesBehavior, Version=1.0.0.0, Culture=neutral, PublicKeyToken=705e34637fdffc54&quot;</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/&gt;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<h1>Create the BizTalk Receive Port and Receive Location</h1>
<p>Next thing to do is to start the BizTalk WCF Service Publishing Wizard. Choose to publish a service endpoint and make sure you enable metadata and create a receive location. In this example we&#8217;ll next choose to &quot;Publish schemas as WCF service&quot; and then define our service by naming service operations and so on.</p>
<p>When you then browse to the URL you choose to publish your service to you&#8217;ll see the nice example of how to instance the service you just defined. </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4wsdl-code-example-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="210" alt="WSDL code example" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4wsdl-code-example-thumb.jpg" width="500" border="0" /></a> </p>
<p>If we then send a request message to service (you&#8217;ll find a client as part of the <a href="http://www.richardhallgren.com/blogfiles/CustomWCFProperties.zip" target="_blank">attached solution here</a>) and inspect the message and its context properties in BizTalk we&#8217;ll see that the username of the calling client is nowhere to be found.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-no-username-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="480" alt="Message No Username" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-no-username-thumb.jpg" width="499" border="0" /></a> </p>
<h1>Configure a WCF-Custom binding and adding a Endpoint Behavior</h1>
<p>To add the username to the message context we&#8217;ll need to add our newly created behavior to our service. We&#8217;ll do this by switch the service over to use a WCF-Custom binding to enable configuration. We then need to add the URL in the address field, define the binding type to a wsHttpBinding and to add our addCustomeWCFProperties behavior to the list of endpoint behaviors.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4add-endpoint-behavior-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="480" alt="Add Endpoint behavior" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4add-endpoint-behavior-thumb.jpg" width="483" border="0" /></a></p>
<blockquote>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-2.gif"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 10px 10px 0px; border-right-width: 0px" height="14" alt="note" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4note-thumb.gif" width="14" align="left" border="0" /></a>&#160; NOTE: there is a limitation in the BizTalk WCF implementation in that you can&#8217;t create the WCF-Custom receive location that uses a HTTP in-process based binding (like the wsHttpBinding used in a WCF-Custom endpoint is) first and then use the WCF Publishing Wizard to only publish a metadata endpoint.</p>
<p><a href="http://www.topxml.com/code/cod-72_10213_biztalk-and-wcf-part-v-publishing-operations-patterns.aspx" target="_blank">Richard Seroter writes about it here</a> and I found the same thing to be true. </p>
<p><em>&quot;This error doesn&#8217;t have to do with mixing MEX endpoints and &#8220;regular&#8221; endpoints in the same IIS web site, but rather, creating MEX endpoints for in-process HTTP bindings seems to trigger this. <b>Note that an IIS-hosted MEX endpoint CAN be created for IIS-hosted HTTP endpoints, but not for in-process hosted HTTP endpoints.&quot;</b></em></p>
<p>If you however choose a different binding that Http or (as in this case) publishes the metadata first and then switches over to a custom binding you&#8217;re ok. </p>
</blockquote>
<p>If we then post another message to the service and inspect the message we&#8217;ll see that the behavior actually added a header and that it&#8217;s part of our BizTalk context properties. The adapter is also smart enough to know that this header isn&#8217;t part of the original headers and therefore stores in it&#8217;s own field within the context properties (you&#8217;ll find as part of the InboundHeaders block as well).</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-username-4.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="221" alt="Message Username" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-username-thumb-1.jpg" width="500" border="0" /></a></p>
<p>One problem remains - the actual value of the user is nested inside a XML node and the property isn&#8217;t promoted.&#160; </p>
<h1>Extract and promote the value</h1>
<p>To extract and promote the value we use an old fashion pipeline component using the following code in the execute method (the complete project is part of the <a href="http://www.richardhallgren.com/blogfiles/CustomWCFProperties.zip" target="_blank">downloadable sample project</a>).</p>
</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5ad57ba1-51bc-4d4d-a29e-20f827ede0e3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #000000; ">        </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            StringReader reader </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> StringReader(inmsg.Context.Read(</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">WindowsUserName</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">, </span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">http://CustomWCFProperties.Schema</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">).ToString());

            </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (reader </span><span style="color: #000000; ">!=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">)
            {
                XPathDocument document </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> XPathDocument(reader);
                XPathNavigator navigator </span><span style="color: #000000; ">=</span><span style="color: #000000; "> document.CreateNavigator();
                </span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> value </span><span style="color: #000000; ">=</span><span style="color: #000000; "> navigator.SelectSingleNode(</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">).Value;
                inmsg.Context.Promote(</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">WindowsUserName</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">, </span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">http://CustomWCFProperties.Schema</span><span style="color: #000000; ">&quot;</span><span style="color: #000000; ">, value);
            }

            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> inmsg;
        }</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</p>
<p>All the component does is reading the XML node the value exists inside and then it reads the actual value. Finally it writes the value back and promotes it. To be able to promote the value we also have to have a <a href="http://msdn2.microsoft.com/en-us/library/aa561059.aspx" target="_blank">Property Schema</a> deployed with a corresponding property name and namespace (WindowsUser and <em>http://CustomeWCFProperties.Schema</em> in this case).</p>
<p>The end results looks something like this.</p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-promoted-username-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="206" alt="Message Promoted Username" src="http://www.richardhallgren.com/wp-content/uploads/2008/04/windowslivewriterwritingbiztalkcontextpropertiestoamessag-72f4message-promoted-username-thumb.jpg" width="504" border="0" /></a> </p>
<p>The username is extracted and promoted and available for example for tracking or to for example use in a routing scenario. </p>
<p>This technique could of course be used for all kinds of scenarios where you like to add information to the context properties and could potentially replace a lot of the classic scenarios for custom pipelines.</p>
<p>All kind of comments are of course more than welcome!</p>
<p><a href="http://www.richardhallgren.com/blogfiles/CustomWCFProperties.zip" target="_blank">Download the sample solution&#160; here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/writing-biztalk-context-properties-to-a-message-from-a-wcf-service-using-behaviors/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Random thoughts on SQL Server Adapter and T-SQL Stored Procedures for BizTalk 2006</title>
		<link>http://www.richardhallgren.com/random-thoughts-on-sql-server-adapter-and-t-sql-stored-procedures-for-biztalk-2006/</link>
		<comments>http://www.richardhallgren.com/random-thoughts-on-sql-server-adapter-and-t-sql-stored-procedures-for-biztalk-2006/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 22:36:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[BizTalk 2006]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/random-thoughts-on-sql-server-adapter-and-t-sql-stored-procedures-for-biztalk-2006/</guid>
		<description><![CDATA[Writing Stored Procedures is an art of its own. As all of you know it&#8217;s very different from writing ordinary code and presents its own kind of problems and issues when it comes to performance, builds, version control, testing etc. This post will try and highlight a few points that I find important when it [...]]]></description>
			<content:encoded><![CDATA[<p>Writing Stored Procedures is an art of its own. As all of you know it&#8217;s very different from writing ordinary code and presents its own kind of problems and issues when it comes to performance, builds, version control, testing etc. This post will try and highlight a few points that I find important when it comes to Stored Procedures, and the especially in a BizTalk and integration related scenario.</p>
<p>Consider the simplified procedure below, I&#8217;ll use is an example for much of the discussion in the rest of the post. Basically the procedure inserts or updates (based on if the optional EmployeeID exists from before or not) employee information to the Employee table of a database named &quot;TestDB&quot;.</p>
<div class="csharpcode">
<pre><span class="kwrd"></span></pre>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:00231690-cb36-4a82-adb3-a42865caf5f6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">Use</span><span style="color: #000000; "> </span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">TestDB</span><span style="color: #FF0000; ">]</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">Go</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">If</span><span style="color: #000000; "> </span><span style="color: #808080; ">Exists</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">select</span><span style="color: #000000; "> </span><span style="color: #808080; ">*</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">From</span><span style="color: #000000; "> dbo.sysobjects </span><span style="color: #0000FF; ">Where</span><span style="color: #000000; "> id </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">object_id</span><span style="color: #000000; ">(N</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #FF0000; ">AddEmployee</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #000000; ">) </span><span style="color: #808080; ">And</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">OBJECTPROPERTY</span><span style="color: #000000; ">(id, N</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #FF0000; ">IsProcedure</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #000000; ">) </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #800000; font-weight: bold; ">1</span><span style="color: #000000; ">) </span><span style="color: #0000FF; ">Drop</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Procedure</span><span style="color: #000000; "> AddEmployeeGo
</span><span style="color: #0000FF; ">Create</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Procedure</span><span style="color: #000000; "> AddEmployee
    </span><span style="color: #008000; ">@EmployeeId</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">Int</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #808080; ">-</span><span style="color: #800000; font-weight: bold; ">1</span><span style="color: #000000; ">,
    </span><span style="color: #008000; ">@LastName</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">Varchar</span><span style="color: #000000; ">(</span><span style="color: #800000; font-weight: bold; ">30</span><span style="color: #000000; ">),
    </span><span style="color: #008000; ">@FirstName</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">Varchar</span><span style="color: #000000; ">(</span><span style="color: #800000; font-weight: bold; ">30</span><span style="color: #000000; ">),
    </span><span style="color: #008000; ">@MiddleName</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">Varchar</span><span style="color: #000000; ">(</span><span style="color: #800000; font-weight: bold; ">30</span><span style="color: #000000; ">)
</span><span style="color: #0000FF; ">As</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">Begin</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">Declare</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentEmployeeId</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">int</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">Declare</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentAction</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">tinyint</span><span style="color: #000000; ">
    </span><span style="color: #008080; ">&#8211;</span><span style="color: #008080; "> Check based on the EmployeeId if the employee exists from before    </span><span style="color: #008080; ">
</span><span style="color: #000000; ">    </span><span style="color: #0000FF; ">If</span><span style="color: #000000; "> </span><span style="color: #808080; ">Not</span><span style="color: #000000; "> </span><span style="color: #808080; ">Exists</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">Select</span><span style="color: #000000; "> EmployeeId </span><span style="color: #0000FF; ">From</span><span style="color: #000000; "> Employee </span><span style="color: #0000FF; ">Where</span><span style="color: #000000; "> EmployeeId </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #008000; ">@EmployeeId</span><span style="color: #000000; ">)
        </span><span style="color: #0000FF; ">Begin</span><span style="color: #000000; ">
            </span><span style="color: #008080; ">&#8211;</span><span style="color: #008080; "> Inserts new employee        </span><span style="color: #008080; ">
</span><span style="color: #000000; ">            </span><span style="color: #0000FF; ">Insert</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Into</span><span style="color: #000000; "> Employee (LastName,FirstName,MiddleName)
            </span><span style="color: #0000FF; ">Values</span><span style="color: #000000; "> (</span><span style="color: #008000; ">@LastName</span><span style="color: #000000; ">, </span><span style="color: #008000; ">@FirstName</span><span style="color: #000000; ">, </span><span style="color: #008000; ">@MiddleName</span><span style="color: #000000; ">)
            </span><span style="color: #0000FF; ">Set</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentEmployeeId</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">Scope_Identity</span><span style="color: #000000; ">()
            </span><span style="color: #0000FF; ">Set</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentAction</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #800000; font-weight: bold; ">1</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">End</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">Else</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">Begin</span><span style="color: #000000; ">
            </span><span style="color: #008080; ">&#8211;</span><span style="color: #008080; "> Updates employee        </span><span style="color: #008080; ">
</span><span style="color: #000000; ">            </span><span style="color: #0000FF; ">Update</span><span style="color: #000000; "> Employee </span><span style="color: #0000FF; ">Set</span><span style="color: #000000; "> LastName </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #008000; ">@LastName</span><span style="color: #000000; ">,
            FirstName </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #008000; ">@FirstName</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">WHERE</span><span style="color: #000000; "> EmployeeId </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #008000; ">@EmployeeId</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">Set</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentEmployeeId</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #008000; ">@EmployeeId</span><span style="color: #000000; ">
            </span><span style="color: #0000FF; ">Set</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentAction</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #800000; font-weight: bold; ">2</span><span style="color: #000000; ">
        </span><span style="color: #0000FF; ">End</span><span style="color: #000000; ">      

    </span><span style="color: #0000FF; ">Select</span><span style="color: #000000; "> </span><span style="color: #008000; ">@currentEmployeeId</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">As</span><span style="color: #000000; "> </span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">@EmployeeId</span><span style="color: #FF0000; ">]</span><span style="color: #000000; ">, </span><span style="color: #008000; ">@currentAction</span><span style="color: #000000; ">
    </span><span style="color: #0000FF; ">As</span><span style="color: #000000; "> </span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">@ProcedureAction</span><span style="color: #FF0000; ">]</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">For</span><span style="color: #000000; "> Xml Path (</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #FF0000; ">Response</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #000000; ">)
</span><span style="color: #0000FF; ">End</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">Go</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</div>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<h1>&#160;</h1>
<h1>Builds and version control</h1>
<p>I always try to have the complete database version controlled. One solution to this that some people advocate is to have a central development database. I have however always found it to be a lot of hassle with overwriting each others changes and so on and always try to make it possible for each developer to build a local version of the database for development. It should also be possible to always check out the latest version and run it to build all the database objects - no matter what you have from before. This is of course a bit tricky when it comes to the actual tables as you might have data and so on (in my opinion it shouldn&#8217;t be the case during development but that&#8217;s another post discussing test data for the database etc). </p>
<p>When it however comes to Stored Procedure as in this post it&#8217;s easy - <strong>drop the old one if it exists and create the new one as in the example</strong>.</p>
<div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7f7a2b5a-1259-4330-8c22-bd3d4b3b61b9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: #0000FF; ">If</span><span style="color: #000000; "> </span><span style="color: #808080; ">Exists</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">select</span><span style="color: #000000; "> </span><span style="color: #808080; ">*</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">From</span><span style="color: #000000; "> dbo.sysobjectsWhere id </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">object_id</span><span style="color: #000000; ">(N</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #FF0000; ">AddEmployee</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #000000; ">) </span><span style="color: #808080; ">And</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">OBJECTPROPERTY</span><span style="color: #000000; ">(id, N</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #FF0000; ">IsProcedure</span><span style="color: #FF0000; ">&#8216;</span><span style="color: #000000; ">) </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #800000; font-weight: bold; ">1</span><span style="color: #000000; ">) </span><span style="color: #0000FF; ">Drop</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Procedure</span><span style="color: #000000; "> AddEmployee
</span><span style="color: #0000FF; ">Go</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">Create</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Procedure</span><span style="color: #000000; "> AddEmployee </span><span style="color: #008000; ">@EmployeeId</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">Int</span><span style="color: #000000; "> </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #808080; ">-</span><span style="color: #800000; font-weight: bold; ">1</span><span style="color: #000000; ">, &#8230;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If found <a href="http://www.codinghorror.com/blog/archives/001050.html" target="_blank">this article</a> by Jeff Atwood over at <a href="http://www.codinghorror.com/blog/" target="_blank">Coding Horror</a> (and <a href="http://odetocode.com/Blogs/scott/archive/2008/01/30/11702.aspx" target="_blank">the articles</a> by K. Scott Allen it links to) very good on how to think about version control database objects. </p>
<h1>Idempotent procedures</h1>
<p>In complex integration solution it&#8217;s a common problem with multiple messages - sending systems might send the same message twice for a number of reasons and one will end up with a shaky system if that causes an error in the integration. I&#8217;ve also seen solutions to this problem where a check is done against the database (say from a BizTalk orchestration) and based on that result a decision is made to call an update or an insert procedure. In my opinion that just unnecessary complexity and database communication. I believe <strong>one should try and handle whether to update or insert inside the procedure as long as that&#8217;s possible and effective</strong>. </p>
<p>I in the AddEmployee Stored Procedure example might receive a EmployeeID as an input parameter and based on a check inside the procedure if the employee exists from before with that id a post is either updated or inserted. </p>
<h1>Response message</h1>
<p>I generally always want two things in return from a Store Procedure like the one in the AddEmployee example (In a select based procedure that would of course be very different as we like all the data in return). </p>
<ol>
<li>The id that been added or changed </li>
<li>What action that&#8217;s been performed (insert or update) </li>
</ol>
<p>What action that was performed is a good idea to return as it&#8217;s quite usual to use this in for example BAM tracking or other logging and so on (we might want know how many employees that was added versus updated for example).</p>
<p>Using the <a href="http://msdn2.microsoft.com/en-us/library/ms189885.aspx" target="_blank">Xml Path syntax</a> for generating the Xml response (thanks again Nick for a <a href="http://www.modhul.com/2008/01/23/an-easier-way-to-do-complex-for-xml-explicit/" target="_blank">great post</a>) from the procedure has made it even simpler to actually skip using the <a href="Add Generated Item " target="_blank">Add Generated Item</a> option in BizTalk. All you have think about is to <strong>set name of the child node the request root node to the same name as the procedure</strong> (in this case AddEmployee). Also remember that the type should be <strong>set up as a Multi-Part Message Type in the orchestrations</strong> you use it from and that the <strong>Receive Pipeline you choose in the Send Port must use a Xml Disassembler component </strong>(XmlReceive pipeline will do fine unless you have your custom pipeline for some reason). </p>
<p><a href="http://www.richardhallgren.com/wp-content/uploads/2008/02/windowslivewritertsqlstoreproceduresforbiztalk-c235schemadbtest-2.jpg"><img style="border-top-width: 0px; border-left-width: 0px;