<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gobbledygooks by Richard Hallgren &#187; RegEx</title>
	<atom:link href="http://www.richardhallgren.com/category/regex/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.richardhallgren.com</link>
	<description>.NET, BizTalk and integration focused scribbles</description>
	<lastBuildDate>Fri, 23 Apr 2010 07:13:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Handle the &quot;bodyTypeAssemblyQualifiedName&quot; SOAP Adapter bug in MSBuild as a RegEx ninja</title>
		<link>http://www.richardhallgren.com/handle-the-bodytypeassemblyqualifiedname-soap-adapter-bug-in-msbuild-as-a-regex-ninja/</link>
		<comments>http://www.richardhallgren.com/handle-the-bodytypeassemblyqualifiedname-soap-adapter-bug-in-msbuild-as-a-regex-ninja/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 12:53:32 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[BizTalk 2006]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[RegEx]]></category>

		<guid isPermaLink="false">http://www.richardhallgren.com/handle-the-bodytypeassemblyqualifiedname-soap-adapter-bug-in-msbuild-as-a-regex-ninja/</guid>
		<description><![CDATA[This is a very specific problem but I&#8217;m sure some of you stumbled over it. When disassembling a XML message in a SOAP port BizTalk can&#8217;t read the message type. This causes problems when for example trying to handle an envelope message and split it to smaller independent messages in the port. It&#8217;s a known [...]]]></description>
			<content:encoded><![CDATA[<p>This is a very specific problem but I&#8217;m sure some of you stumbled over it. When disassembling a XML message in a SOAP port BizTalk can&#8217;t read the message type. This causes problems when for example trying to handle an envelope message and split it to smaller independent messages in the port. It&#8217;s a known problem discussed <a href="http://blogs.msdn.com/richardbpi/archive/2006/09/15/Fixing-_2200_SOAP-_2F00_-Envelope-Schema_2200_-Error-In-BizTalk.aspx" target="_blank">here</a> and <a href="http://www.digitaldeposit.net/saravana/post/2007/08/17/SOAP-Adapter-and-BizTalk-Web-Publishing-Wizard-things-you-need-to-know.aspx" target="_blank">here</a> (you also find information about it in the <a href="http://download.microsoft.com/download/3/7/6/376a6f6c-8c97-4ab5-9d5a-416c76793fbb/bts06developerstroubleshootingguide.doc" target="_blank">BizTalk Developer&#8217;s Troubleshooting Guide</a>) and the solution is to make a small change in the generated web service class. Below is a small part of he generated class.</p>
<pre class="c#:collapse:showcolumns" name="code">//[cut for clarity] ...
            Microsoft.BizTalk.WebServices.ServerProxy.ParamInfo[] outParamInfos = null;
            string bodyTypeAssemblyQualifiedName = "XXX.NO.XI.CustomerPayment.Schemas.r1.CustomerPayments_v01, XXX.NO.XI.CustomerPaym" +
                "ent.Schemas.r1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ac564f277cd4488" +
                "e";
            // BizTalk invocation
            this.Invoke("SaveCustomerPayment", invokeParams, inParamInfos, outParamInfos, 0, bodyTypeAssemblyQualifiedName, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, true, false);
        }
    }
}</pre>
<p>Basically the problem is that the generated code puts the wrong <em>DocumentSpecName </em>property in the message context. I&#8217;ll not dicusses the problem in detail here but Saravana Kumar does thorough dissection of the problem in <a href="http://www.digitaldeposit.net/saravana/post/2007/08/17/SOAP-Adapter-and-BizTalk-Web-Publishing-Wizard-things-you-need-to-know.aspx" target="_blank">his post</a> on it. </p>
</p>
<p>The solution is to update the <em>bodyTypeAssemblyQualifiedName</em> to set a null value. That will cause the <em>XmlDiassasemler</em> to work as we&#8217;re used to and expect.</p>
<blockquote>
<p>If the value <em>null</em> is passed instead of <em>bodyTypeAssemblyQualifiedName</em>, SOAP adapter won&#8217;t add the <em>DocumentSpecName</em> property to the context. Now, when we configure our auto-generated SOAP<em>ReceiveLocation</em> to use <em>XmlReceive</em> pipeline, the <em>XmlDisassembler</em> component inside <em>XmlReceive</em> will go through the process of automatic dynamic schema resolution mechanism, pick up the correct schema and promotes all the required properties (distinguished and promoted) defined in the schema and it also promotes the <em>MessageType</em> property.</p>
<p><strong>From:</strong> <a href="http://www.digitaldeposit.net/saravana/post/2007/08/17/SOAP-Adapter-and-BizTalk-Web-Publishing-Wizard-things-you-need-to-know.aspx">http://www.digitaldeposit.net/saravana/post/2007/08/17/SOAP-Adapter-and-BizTalk-Web-Publishing-Wizard-things-you-need-to-know.aspx</a></p>
</blockquote>
<pre class="c#" name="code">//[cut for clarity] ...
            Microsoft.BizTalk.WebServices.ServerProxy.ParamInfo[] outParamInfos = null;
            string bodyTypeAssemblyQualifiedName = null;
            // BizTalk invocation
            this.Invoke("SaveCustomerPayment", invokeParams, inParamInfos, outParamInfos, 0, bodyTypeAssemblyQualifiedName, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, true, false);
        }
    }
}</pre>
<p>But if you have an automated deployment process you probably use <a href="http://geekswithblogs.net/michaelstephenson/archive/2006/09/16/91369.aspx" target="_blank">MSBuild to generate your Web Services</a>. Then is soon becomes <strong><em>very </em></strong>annoying to remember to update the .cs-file again and again for every deployment. <strong>So how can we script that update?</strong> </p>
<p>First we need to find a regular expression to find the right values. With some help from <a href="http://stackoverflow.com/" target="_blank">StackOverflow</a> (let&#8217;s face it, there are some <strong><em>crazy</em></strong> regular expressions skills out there &#8230;) I ended up on the following.</p>
<pre class="xml" name="code">(?&lt;=string\sbodyTypeAssemblyQualifiedName\s=\s)(?s:[^;]*)(?=;)</pre>
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 15px; border-right-width: 0px" height="183" alt="ninja5" src="http://www.richardhallgren.com/wp-content/uploads/2008/11/windowslivewriterhandlethebodytypeassemblyqualifiednameso-adf4ninja5-thumb.jpg" width="240" align="right" border="0"> If you&#8217;re not a RegEx ninja the line above does something like this:&nbsp;
<ol>
<li>After the string &#8220;string bodyTypeAssemblyQualifiedName = &#8221;
<li>turn on single line (treat &#8220;\r\n&#8221; as any other character) ( this is what &#8220;(?s: )&#8221; does)
<li>match every character that is not a semicolon
<li>until a single semicolon is reached. </li>
</ol>
<p>Then I used a task from the <a href="http://www.codeplex.com/sdctasks" target="_blank">SDC Task library</a> (you probably already use this if you&#8217;re using MSBuild and BizTalk). More specially we use the <em>File.Replace</em></p>
<pre class="xml" name="code">&lt;Target Name="FixSOAPServiceCode"&gt;
    &lt;File.Replace
            Path="$(WebSiteServicePath)CustomerPaymentService\App_Code\CustomerPaymentService.asmx.cs"
            Force="true"
            NewValue="null"
            RegularExpression="(?&amp;lt;=string\sbodyTypeAssemblyQualifiedName\s=\s)(?s:[^;]*)(?=;)"&gt;
    &lt;/File.Replace&gt;
&lt;/Target&gt;</pre>
<p>Now this task is part of the build script and called right after the tasks that generates the web service. This saves me a lot of manual work and potential errors! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhallgren.com/handle-the-bodytypeassemblyqualifiedname-soap-adapter-bug-in-msbuild-as-a-regex-ninja/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
