Jan 092009

I was currently developing the Bulk XML import adapter and I had developed the adapter and tested it on my development box. I then proceeded to create the MSI.

So you go and create the code for the adapter, and test the functionality of the logic.

After you are done, you have to create the Adapter Registry File. The easiest way to do this is to use the Adapter Registry Wizard, which will create a registry file.

Here is the sample file I created:

Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\CLSID\{16e07168-8136-4804-8a6f-33053ad09d62}] @="SQLBulkXML Adapter" "AppID"="{14E0EF65-3B1B-4e29-9923-C13CDE2998B0}" [HKEY_CLASSES_ROOT\CLSID\{16e07168-8136-4804-8a6f-33053ad09d62}\BizTalk] @="BizTalk" "TransPortType"="SQLBulkXML" "Constraints"=dword:00002502 "OutboundProtocol_PageProv"="{2DE93EE6-CB01-4007-93E9-C3D71689A283}" "TransmitLocation_PageProv"="{2DE93EE6-CB01-4007-93E9-C3D71689A282}" "OutboundEngineCLSID"="{d70b9447-641d-4af7-8324-9996d124a66a}" "OutboundTypeName"="StottIS.BizTalk.Adapters.Runtime.SQLBulkXMLTransmitter.SQLBulkXMLTransmitAdapter" "OutboundAssemblyPath"="C:\\WINDOWS\\assembly\\GAC_MSIL\\SQLBulkXMLTransmitAdapter\\\\SQLBulkXMLTransmitAdapter.dll" "AdapterMgmtTypeName"="StottIS.BizTalk.Adapters.SQLBulkXMLDesignTime.AdapterManagement" "AdapterMgmtAssemblyPath"="C:\\WINDOWS\\assembly\\GAC_MSIL\\SQLBulkXMLAdapterManagement\\\\SQLBulkXMLAdapterManagement.dll" "AliasesXML"="<AdapterAliasList><AdapterAlias>sqlbulkxml://</AdapterAlias></AdapterAliasList>" "PropertyNameSpace"="http://schemas.microsoft.com/SQLBulkXML" "SendHandlerPropertiesXML"="<CustomProps><AdapterConfig vt=\"8\"/></CustomProps>" "SendLocationPropertiesXML"="<CustomProps><AdapterConfig vt=\"8\"/></CustomProps>" [HKEY_CLASSES_ROOT\CLSID\{16e07168-8136-4804-8a6f-33053ad09d62}\Implemented Categories] [HKEY_CLASSES_ROOT\CLSID\{16e07168-8136-4804-8a6f-33053ad09d62}\Implemented Categories\{7F46FC3E-3C2C-405B-A47F-8D17942BA8F9}]

Which created the following entry in the registry:


I created the adapter, registered the adapter in the registry and then imported the adapter into the adapter list and configured it.

Things worked great, and I was ready to create the install package so I could use the code in other environments.

I installed the code and started running, however, I started getting errors that the connection string was not property formatted.

This did not make sense, so I put the code on the installed box and started debugging the code.

When I got to the loading of the configuration, I was getting a null string for the AdapterConfig in this method:

public SQLBulkXMLTransmitProperties(IBaseMessage message, string propertyNamespace) { XmlDocument locationConfigDom = null; string config = (string) message.Context.Read("AdapterConfig", propertyNamespace); this.isTwoWay = (bool) message.Context.Read(isSolicitResponseProp.Name.Name, isSolicitResponseProp.Name.Namespace); if (null != config) { locationConfigDom = new XmlDocument(); locationConfigDom.LoadXml(config); this.LocationConfiguration(locationConfigDom); } }


So when it got to the resolution of the AdapterConfig:

public string ConnectionString { get { return this.connectionString; } }

It would resolve to null.


The issue ended being in the install project, I put http://stottis.com/bulkxml instead of http://schemas.microsoft.com/SQLBulkXML


Once that was changed (I actually changed it in the registry and in the adm_Adapter table, it started working as expected:


So, it makes sense, what happens is that the BizTalk port, after the pipeline is complete, it then reads the configuration, and attaches the particular send port configuration to the message and sends the message to the appropriate dll that is defined in the adm_Adapter table, that adapter dll, then extracts the configuration and sends it off as is is programmed.


This is probably common knowledge, but I have been too busy making every flavor of mistakes that can be made, to look at the core functionality of how BizTalk actually works.

Hope that this explains what is going on a little bit.