Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Neil Gibbons 144 posts 61 karma points
    Feb 24, 2010 @ 11:52
    Neil Gibbons
    0

    MSXML Script & .NET

    Trying to get at the BrowserCapabilities class via msxml:script but keep getting an error every time a save. 

    Code:

     

    <msxsl:script language="c#" implements-prefix="randomTools">
      <msxsl:assembly href="../bin/umbraco.dll"/>
      <msxml:using namespace="System.Web" />
      <![CDATA[
          /// <summary>
          /// Gets a random integer that falls between the specified limits
          /// </summary>
          /// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param>
          /// <param name="upperLimit">An integer that defines the upper-boundary of the range</param>
          /// <returns>A random integer within the specified range</returns>
          public static int GetRandom(int lowerLimit,int upperLimit) 
          {
              Random r = umbraco.library.GetRandom();
              int returnedNumber = 0;
              lock (r)
              {
                  returnedNumber = r.Next(lowerLimit, upperLimit);
              }
              return returnedNumber;
          }
    
          public string GetJavaScript()
          {
              System.Web.HttpBrowserCapabilities browser = Request.Browser;    
                    return browser.EcmaScriptVersion.ToString();
          }
      ]]>
    
    </msxsl:script>

    I know its not the GetRandom method and the new GetJavaScript isn't even called anywhere yet.

    Error:

     

    Error occured
    Error in XSLT at line 75, char 17
    73:       public string GetJavaScript()

     

    74:       {

    75: >>>   System.Web.HttpBrowserCapabilities 
    browser = Request.Browser; <<<

    76:       return 
    browser.EcmaScriptVersion.ToString();
    77:       }

     

     

    Any ideas?

    Is the Request object cont available in this context?

    Neil

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Feb 24, 2010 @ 12:06
    Lee Kelleher
    1

    Hi Neil,

    You'd probably need to explicitly call the Request object via "HttpContext.Current.Request"?

    I'd recommend moving any C# code to a separate XsltExtension DLL ... as the <msxml:script> blocks compile for each page request - major performance hog!

    Cheers, Lee.

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Feb 24, 2010 @ 12:20
    Ismail Mayat
    0

    Neil,

    Why not get browser using js eg:

    <msxsl:script implements-prefix="myFuncs" language="JavaScript"> 
    
    <![CDATA[
    
    function getClientTime(){
        var now = new Date();
        return now.getHours();
    }
    
    ]]>
    
    </msxsl:script> 

    Replace with your method and using js get whatever u need regarding the browser.

    Regards

    Ismail

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Feb 24, 2010 @ 13:02
    Douglas Robar
    101

    @Lee, I don't think it's true that script blocks are compiled for each page request. If they were, there would be no reason to compile them with the

    XslCompiledTransform()

    in umbraco as the speed gain would be lost by the compile-time overhead I should think. Instead, the macro is compiled when it is saved in the umbraco UI or when the macro is run the first time after an application pool restart. At least that's my understanding (someone correct me if I'm wrong)

    The real reason for not using script blocks is much more about security than performance... you can't use script blocks in a medium trust hosting evironment, which is why Benjamin is pushing for moving script blocks to app_code or dll extensions instead. Performance-wise, there shouldn't be a significant difference.

    And, the issue with files being written to the temp folder is only when you have debugging turned on in your web.config, which you should not have in a production environment anyway. More details about temp folders and script blocks in the comments of this blog post...http://blog.percipientstudios.com/2009/9/21/advanced-xslt-with-net-namespaces.aspx

     

    @Niel, you may find this blog post helpful as well, giving a good background for the kind of thing you're trying to do. http://blog.percipientstudios.com/2009/9/21/advanced-xslt-with-net-namespaces.aspx

     

    cheers,
    doug.

  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 24, 2010 @ 13:03
    Jamie Howarth
    0

    Be careful, <msxml:script> still hogs regardless of language. You could just write a <script type="text/javascript"> client-side block, or does the browsers capabilities need to be handled/rendered by XSLT?

    Best,

    Benjamin

  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 24, 2010 @ 13:06
    Jamie Howarth
    1

    @Doug, if <msxml:script> is present in the page, yes you are wrong. :-)

    When script is present, the code is compiled on each and every request and compiles to the %TEMP% directory, which can very quickly overflow. Microsoft have an article on MSDN about the subject and it's vulnerability, hence the whole removing <msxml:script> on Medium Trust thing and subsequent workaround to use App_Code. 

    Normal XSLT macros can a) be cached and b) are compiled and cached on first request providing that <msxml:script> is not present.

    Best,

    Benjamin

  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 24, 2010 @ 13:10
    Jamie Howarth
    0

    P.S. Try debugging an Umbraco site with XSLT in it - Cassini will output the precise directory where the <msxml:script>-containing XSLT is compiled to - on Vista and Windows 7 this is somewhere in X:\Users\username\AppData\Local\Temp. This is done on each and every single request for an XSLT macro containing script - if you are running a high-traffic site this could easily max out your OS hard disk space if left unchecked.

    P.P.S. This behaviour is by design with XslCompiledTransform, it's not a debug-dependent behaviour.

    P.P.P.S. Performance is a massive improvement when not using <msxml:script>. App_Code gets cached at the ASP.NET and IIS level, <msxml:script> doesn't.

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Feb 24, 2010 @ 13:20
    Lee Kelleher
    0

    @Doug, Benjamin Howarth - a fountain of coding knowledge!  I wasn't aware of any of these <msxml:script> issues until chatting Benjamin!

    We live and learn!

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Feb 24, 2010 @ 13:50
    Douglas Robar
    0

    Aha... more research and more knowledge... what a great thing!

    I'm all in favor of moving to app_code extensions for medium trust support but if the macros will be faster as well... heck, I'm there! (and yes, I've got a blog post half written to explain it all... oh for more hours in the week to do everything!)

    Thanks, Benjamin, looking forward to 4.1 even more now!

    cheers,
    doug.

  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 24, 2010 @ 14:29
    Jamie Howarth
    2

    The simple trickery of it is that App_Code gets treated exactly the same as traditional XSLT extensions do - as pre-compiled assemblies - it's the one place in a web application project where C#/VB code is compiled and treated just like a pre-compiled assembly or library.

    This means they're cached = faster. They're strongly-typed = safer. And with the [XsltExtension] header, it's a doddle migrating your <msxml:script> over without breaking an inch of your functionality. And they debug in Visual Studio. And they work in Medium Trust. And with all of that, you can run more Umbraco sites on a single server = cheaper.

    Oh heck, I'll just link to my Feb16 presentation :-D 

    Benjamin

  • Neil Gibbons 144 posts 61 karma points
    Feb 24, 2010 @ 15:07
    Neil Gibbons
    0

    Cheers,

    Doug, your article helped fix my immediate problem - adding the namespace to "System.Web" isn't enough, I had to add the msxsl:assembly for it too.

    However, I'll look to get the code out of here altogether and into App_Code as soon as I can. 

    Thanks for the info.

  • Neil Fenwick 86 posts 63 karma points
    Feb 24, 2010 @ 17:15
    Neil Fenwick
    0

    @Benjamin

    I'm assuming if you turn on caching for the Macro that corresponds to the XSLT with the <msxml:script> in it, then that would mitigate effect of the performance / DOS issue?

  • Jamie Howarth 306 posts 773 karma points c-trib
    Feb 24, 2010 @ 21:59
    Jamie Howarth
    0

    Neil,

    Unfortunately not. Turning on caching will add the macro to the ASP.NET application cache when first requested, but because of the recompilation every time, the generated temporary file has a unique name, which means the cached macro is never utilised, as there is high-level coupling between the cache and the temp files.

    Best,

    Benjamin

Please Sign in or register to post replies

Write your reply to:

Draft