XslLoadException: The type or namespace name ‘SecurityRulesAttribute’ does not exist in the namespace ‘System.Security’ (are you missing an assembly reference?)

While porting a project from .Net 3.5 to .Net 4 we got this weird error. The error occurs when loading an XSLT in memory. Here is the failing piece of code (simplified):

private static XslCompiledTransform ReadXslt(string fname) { XslCompiledTransform xsl = new XslCompiledTransform(); XsltSettings settings = new XsltSettings(false, true); xsl.Load(fname, settings, new XmlUrlResolver());

return xsl; }

The XSLT file being loaded contains C# script:

<msxsl:script language=”C#” implements-prefix=”user” xmlns:user=”urn:my-scripts” xmlns:msxsl=”urn:schemas-microsoft-com:xslt”>
  <![CDATA[
   public string Format(string s, int n)
   {
     if (s.Length < n)
     {
        s = new string(‘0’, n – s.Length) + s;
     }
     return s.Substring(0,n);
   }
  
   // other functions

    ]]>
</msxsl:script>

According to several websites setting the enableScript property in the XsltSettings to true should solve the problem and mostly they are right. But for some weird reason loading the XSLT in this format in a VS Test project keeps failing. I haven’t found the reason, but I did find the working solution!

Checking security on the XSLT files, moving the files directly under the application, … all didn’t work. So moving this application to production would work, only the tests fail Emoticon die tong uitsteekt

Looking further I fell on this web site: http://msdn.microsoft.com/en-us/library/system.xml.xsl.xsltargumentlist.addextensionobject(v=vs.100).aspx. They suggest to use extension objects containing the C#code instead of writing the code inside the XSLT file. This requires a bit more work on the C#side, but it works everywhere (including in the test project).

image

The (partial) code:

private static readonly XmlUrlResolver _myResolver = new XmlUrlResolver();

private static XslCompiledTransform ReadXslt(string fname)
{
    XslCompiledTransform xsl = new XslCompiledTransform();
    XsltSettings settings = new XsltSettings(false, true);
    xsl.Load(fname, settings, _myResolver);
   
    return xsl;
}

// Additional work in transforming the file (remove C# code from the XSLT file)

private class XsltFunctions
{
    public string Format(string s, int n)
    {
        if (s.Length < n)
        {
            s = new string(‘0’, n – s.Length) + s;
        }
        return s.Substring(0, n);
    }
    // Other functions
}

private static XmlDocument TransformOrganisation(string fname, XmlDocument xml)
{
    // Create an XsltArgumentList, to be passed into the Transform() function
    xsltArgs = new XsltArgumentList();
    XsltFunctions ext = new XsltFunctions();
    xsltArgs.AddExtensionObject(“urn:my-scripts”, ext);

    // Transform in memory
    XslCompiledTransform xct = ReadXslt(fname);
    XmlDocument xformed;
    using (MemoryStream ms = new MemoryStream())
    {
        XmlWriter wtr = XmlWriter.Create(ms);
        xml.WriteContentTo(wtr);
        wtr.Close();

        ms.Seek(0, SeekOrigin.Begin);            // reset stream
        XmlReader rdr = XmlReader.Create(ms);
        using (MemoryStream ms2 = new MemoryStream())
        {
            XmlWriter wtr2 = XmlWriter.Create(ms2);

            xct.Transform(rdr, xsltArgs, wtr2);
            xformed = new XmlDocument();
            ms2.Seek(0, SeekOrigin.Begin);        // reset stream
            xformed.Load(ms2);
        }
    }
    return xformed;
}

Using C# script (or any other not-XSLT extensions) inside XSLT files is now being deprecated, so this is the way to add additional functions to your XSLT files. It is safer because it won’t allow somebody to change your XSLT file and run arbitrary code.

About Gaston

MCT, MCSD, MCDBA, MCSE, MS Specialist
This entry was posted in .Net, Development and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s