Assembly loading policy from the GAC

UPDATE: This does not apply to BizTalk … I’ve made an update post here. Sorry.

We’re working with a lot of code libraries that we use in different parts of our BizTalk solutions. As the are used on several servers and by loads of different “BizTalk parts” (both in orchestrations and maps) it’s important that we always keep the version number of the assemblies up to date. That means that every little change should increase the current version number. But as they are used in so many places people have started to skip this step as they thought they had to compile all parts that should use the new code (say it’s a bug fix and you’d like all “using parts” of the assembly to load the updated version). This is where GAC loading policy comes to the resource!

First we have to understand that every .NET assembly is identified using four characteristics:

  • Assembly name
  • Major or minor version
  • Public key token
  • Culture

Then we need to know that the first version number in for example version 1.1.2.1 is the major version. The second is the minor version and the third and fourth are build, revision version number. So this means that if you have 1.1.2.1 installed and make a minor change the easiest way to use the new assembly is to change the one of the build or revision numbers (the third or fourth number). Then the CLR will load the new assembly without any other changes!

But sometimes we have to change the minor or major version – and we still don’t have to recompile a thing! We can use a publisher policy file. This is an example of such a file defined for version 1.0.0.0 moving to 2.0.0.0.

<div><span style="color: #0000FF; "><</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">runtime</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">assemblyBinding </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">="urn:schemas-microsoft-com:asm.v1"</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">dependentAssembly</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
                </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">assemblyIdentity </span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="BaseHelper"</span><span style="color: #FF0000; "> publicKeyToken</span><span style="color: #0000FF; ">="18517ea673f8584b"</span><span style="color: #FF0000; "> culture</span><span style="color: #0000FF; ">="neutral"</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/></span><span style="color: #000000; ">
                    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">bindingRedirect </span><span style="color: #FF0000; ">oldVersion</span><span style="color: #0000FF; ">="1.0.0.0"</span><span style="color: #FF0000; "> newVersion</span><span style="color: #0000FF; ">="2.0.0.0"</span><span style="color: #0000FF; ">/></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">dependentAssembly</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">assemblyBinding</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">runtime</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">></span></div>

This kb article describes what to do next:

  1. Change the version and recompile. The first step is to create the new version of your component. After you’ve done that, you will need to modify the version number in the AssemblyInfo file for your component.
    Create the publisher policy file. Create the publisher policy file for the assembly using the format shown above.
    Use Assembly Linker (Al.exe) to create the publisher policy assembly. The Assembly Linker is included with the .NET Framework SDK. To create the publisher policy assembly that redirects a binding from version 1.0 of Website.dll to version 2.0 using a publisher policy file called website.config, run the following command:

    al /link:BaseHelper.config /out:policy.1.0.BaseHelper.dll /keyfile:c:keyfile.snk

This command will create a new assembly called policy.1.0.BaseHelper.dll. This naming convention is important, as indicated in the “What Is a Publisher Policy Assembly?” section.

  1. Install the publisher policy assembly into the Global Assembly Cache. The publisher policy assembly is installed into the GAC. It will be used by the .NET runtime when any application attempts to bind to version 1.0 of the BaseHelper.dll, and it will force the application to bind to the new version automatically.

  2. Install the new version into the Global Assembly Cache. Install the new version of the component into the GAC. After the new version has been installed, the old version can be safely removed.

So no more excuses for not updating the version number!

Web service times out before the orchestration completes

Today we ran into some problems when making a call to a web service that took more than 90 seconds via the SOAP adapter. After 90 seconds we got a “System.Net.WebException: The operation has timed-out” error in return. It turned out that we had to set the SOAP.ClientConnectionTimeOut context property for the request message. We did this in the message construction using the following code.

<div><span style="color: #000000; ">MyRequestMessage(SOAP.ClientConnectionTimeout) = 200000;</span></div>

I found this post by Thomas Restrepo useful for understanding both the problem and solution. Apparently the default value is 90000 (90 seconds) before the adapter times out. This article on MSDN is also an excellent read when working with web services and BizTalk server.

BOM – Byte Order Mark in BizTalk output

Today was another day of new BizTalk problems … The task was easy; produce a XML file and send to a receiving system. Fine. Done. … Not.

The receiving system could not read the file because of some strange characters in the beginning of the file! It looked something like the below when opening the file in a fancy text editor (UltraEdit or TextPad for example).

<div><span style="color: #000000; ">i»¿</span><span style="color: #0000FF; "><?</span><span style="color: #FF00FF; ">xml version="1.0" encoding="utf-8"</span><span style="color: #0000FF; ">?></span></div>

After a couple of very interesting (:/) hours of Googling) I found this from Ben McFarlin

>
> It is because internal BizTalk messages are in UTF8 format and include
the byte order mark. When you added the xml declaration for UTF16 it
confused the engine; the declaration read UTF16 but the byte order mark indicated UTF8.
>
>

When I finally found the cause the solution was easy. Just another of those weird properties … This time it’s called Preserve BOM (on the properties of the XML Assembly pipeline component – see figure on the right). BOM of course stands for Byte Order Mark.

Nevermind the XML namespaces in Xpath expressions

Understanding Xpath expressions is definitely a success factor when working with BizTalk development. Xpath is extremely powerful (when one gets it right) but it’s one of the must frustration techniques I’ve ever worked with! Xpath is one of those languages that either gives you to answer you want to a query – or (more often) just doesn’t give you anything in return! In 99 percent of the cases this means that you missed something in your match. In 99 percent of these cases this means that you got some problems with namespaces in the XML document your querying (This is certainly true when working with BizTalk that “namespace-heavy”). One technique to get around this is to use the same approach as BizTalk itself uses – the Xpath local-name() function!

Consider the following XML document.

<div><span style="color: #0000FF; "><</span><span style="color: #800000; ">Message </span><span style="color: #FF0000; ">xmlns:ns0</span><span style="color: #0000FF; ">="Standard.Envelope/1.1"</span><span style="color: #FF0000; "> xmlns:xsi</span><span style="color: #0000FF; ">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">ns0:Envelope</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">Header</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">MessageTypeInfo</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
                </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">MessageType</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">.</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">MessageType</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">MessageTypeInfo</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">Action</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">INSERTED</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">Action</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">Addressees</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
                </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">SenderCode</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">Mill</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">SenderCode</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
            </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">Addressees</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
        </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">Header</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
    </span><span style="color: #0000FF; "></</span><span style="color: #800000; ">ns0:Envelope</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">Message</span><span style="color: #0000FF; ">></span></div>

The Xpath expression below will hit the Envelope node. But is’s very fragile! As soon as the namespace prefix changes (It might change to ns1 and namespace ns0 will be used for something else.) you’ll end up with an empty result.

<div><span style="color: #000000; ">/Message/ns0:Envelope</span></div>

However, if one uses the below expressions instead – that makes use of the local-name function – it ignores the namespace and only cares about the name of the node (Envelope that is ;)). And this is of course far less sensitive to change.

<div><span style="color: #000000; ">/Message/*[local-name()='Envelope']</span></div>

BizTalk Deploy Tool

I’m currently working in a stabilization phase on a deployment application for BizTalk 2006 projects. We based the solution on the Enterprise Solutions Build Framework and the BizTalk Explorer Object Model. Basically our solution has a GUI that makes it possible to point out which artifacts one likes to deploy (from the developers local BizTalk server).

The application then figures out all the dependencies that the selected artifacts has (In our solution an Orchestration for example might have > 20 dependencies to different schemas, pipelines, C# libraries etc, etc).

All DLL:s of the different artifacts are then extracted from the local GAC (where they exist when deployed to the local BizTalk). These DLL:s are then packed in to one single deployment package also containing a single XML file that keeps track of the dependencies and the order of witch they have to be deployed in BizTalk (the most depending schemas first and so on). The XML file also contains other meta data information such as ports the artifacts use etc.

This package is then loaded into another part of the application were it’s possible to point out the different servers one like to deploy to. This view then shows information about what has to be done on the server to make it possible to deploy without conflicts (One might have running Orchestration or suspended messages for example that has to be stopped or terminated.). At this stage we also check the naming of the different artifacts. These have to comply with the naming conventions that are configured in the config file of the applications (a warning is shown if the artifact doesn’t validate towards these).

When no warnings (its possible to override a warning) or conflicts are shown one can deploy. We then move the deploy scripts to the servers and use the MSBuild tasks in the SBF to deploy everything for us. We really saved some serious time with this approach and even if it took us a while to get everything working it’s been well worth it!

We have a huge feature list for the next phase of the tool and are planing to and support for BizUnit tests in the DLL:s (so that one gets a warning when deploying a Orchestration without etc). We also like to add more meta data about the port and make it possible to configure new ports as a part of the deployment process. Etc, etc …

Feel free to comment or write we line for further information about this approach. It would also be interesting to hear about other approaches for deployment and what kind of features these solutions have.

XML comment in BizTalk output message

We ran into an issue today when we had to have an XML comment just below the XML declaration in a message we’re producing in our BizTalk 2006 solution. We needed to produce something like the below.

<div><span style="color: #0000FF; "><?</span><span style="color: #FF00FF; ">xml version="1.0"</span><span style="color: #0000FF; ">?></span><span style="color: #000000; ">
</span><span style="color: #008000; "><!--</span><span style="color: #008000; "> Comment goes here </span><span style="color: #008000; ">--></span></div>

Our first approach was to create a map in the send port and to have a custom XSLT template in there that added the comment before the whole transformation process started. We actually got this to work but it meant that we had to have a whole new map with a separate XSLT document in the project!

Eventually we found a property called Xml Asm Processing Instructions (highlighted in the figure – click it to view it in original size) on the XML assembly component (used in the standard XMLTransmit pipeline).

We just put the comment as a value in this property and we were done! No new artifacts or code! Just a weird property – typical BizTalk behavior!

Visual Studio Database Project

I’ve realized that I never understood the full potential of the Visual Studio Database Project. None of the projects I’ve worked on has had a effective process on handling changes and versioning of the database schema. Test data, build scripts, changes to the local development database versus the test and production base has also been a bit bumpy. I’ve haven’t understood that working with the Database Project potentially could solves a lot of these challenges .

A chapter from the Database Access with Visual Basic® .NET book describes some features in the Database Project.