Commerce Server doesn’t like ampersands in variant IDs
Recently while developing an eCommerce solution for a client using Microsoft Commerce Server 2009 and SharePoint 2007 we ran into an interesting bug.
Our client is populating their Commerce Server catalog with a data dump from an existing back-end system. They generate a valid XML file and import it using Commerce Server’s Catalog Manager application, then we use some standard Commerce Server starter site web parts to pull out products and apply custom XSL style sheets.
This setup worked fine during initial phases of the project, but about a week ago we suddenly started getting:
System.Xml.XmlException: An error occurred while parsing EntityName.
For reference, the complete stack trace is available here.
The culprit
Given the nature of the exception and my previous experience with XSL transforms choking on invalid XML we started looking at the XML data dump from our client searching for funky characters in odd places. Sure enough, it turns out that the client had decided to use the ‘&’ character in their Variant IDs.
The client had thought ahead and properly escaped that ampersand such that the Variant ID in the XML data dump was coded like this:
[xml] <variantid=’458960&56’> [/xml]
When that gets imported into Commerce Server via the Catalog Manager it gets correctly decoded to a Variant ID of “458960&56”. When the ProductDetails Web Part pulled the Variant ID out of Commerce Server and generated new XML in-memory against which to apply our XSL, it failed to re-encode that pesky ampersand and the XSL transform choked on an invalid literal ‘&’.
The solution
Turns out the solution was fairly simple:
Double escape that ‘&’ in the initial XML data dump.
Our doubly-escaped ampersand now looks like this:
[xml] <variantid=’458960&amp;56’> [/xml]
When loaded into Commerce Server’s Catalog Manager it is correctly decoded once so that the Variant ID that lives inside Commerce Server’s database now looks like “458960&56” and when loaded into the XSL transformation engine it is properly parsed as “458960&56”.
Simple, right?