Wednesday 13 November 2013

Static Content in IIS 7.5

It's amazing how almost every piece of advice you read about something can be completely, utterly, totally useless. I think it's an endemic problem of developers who only spend time clicking the shiny buttons in the GUI of products without ever actually getting into the guts of a thing to see what is happening.

Anyway, a designer was trying to add .SVG, .ICO and .WOFF files to our website which worked fine locally but when viewed on our UAT server it was coming up with 404 errors for those files.

After a little head scratching, I found out that IIS disables transport for those extensions by default. When looking around for advice as to how to switch transport back on for these, I read so many articles where clearly the author never bothered to go near the web.config file.

And of the advice that did cover the web.config file, most of the received wisdom goes along the lines of:

Add these lines to the web.config:

    <system.webServer>
    ...
    <staticContent>
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
        </staticContent>
    </system.webServer>


Which is great in theory, but this actually results massive amounts of errors on the site as it suddenly fails to load ALL STATIC CONTENT. So no CSS, JS, images, anything, plus a load of odd redirections for other types.

I figured that having these rules in a separate web.config file in our static resources folder might help, so I tried that and although the site was now generally working again, there were mysterious 500 errors for the .SVG etc requests.

After a little digging, I found this post on Stack Overflow:

http://stackoverflow.com/questions/13677458/asp-net-mvc-iis-7-5-500-internal-server-error-for-static-content-only/13677506#13677506

This saved me a complete metric fuck-tonne of time.

What all the advice I had read was missing is that you should remove the mappings in the static content before you add them, or you will get a 500 error that doesn't appear in any log unless you enable the really paranoid stuff in IIS.

So, the proper version of what the file looks like is this, remembering that this is a partial web.config sitting in our static resources folder:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
    <staticContent>
<remove fileExtension=".woff"/>
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
<remove fileExtension=".svg"/>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<remove fileExtension=".ico"/>
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
        </staticContent>
    </system.webServer>
</configuration>


Antaris RazorEngine and Mono-3.2.3

After some machinations, I managed to get Antaris RazorEngine working with Mono-3.2.3.

After making and installing mono from a tarball (http://download.mono-project.com/sources/mono/), I took the latest version of RazorEngine down from github (https://github.com/Antaris/RazorEngine), compiled using mono's xbuild tool, and then took the version of RazorEngine.dll and System.Web.Razor.dll from the RazorEngine.Core folder and used that within my applications. I removed all instances of System.Web.Helpers, System.Web.Mvc, System.Web.WebPages, WebMatrix, etc as those would have conflicted references.

And RazorEngine is now really horribly strict :( It throws compile exceptions on warnings which is wholly irritating. I'll have to revisit and police every single template and make sure they are compatible.

I also noticed that the new version of xsp4 required me to be in the root folder of the website even though I was setting the root on the command line.

Anyway, glad to see it working again, even if it will be a chore to get it fully compatible. I guess it is balanced out by now being on .Net 4.5 compatible mono.

Update: I've made an adjustment to the RazorEngine code which stops it treating warnings as errors during template compilation.

Modify RazorEngine.Core/Compilation/DirectCompilerServiceBase.cs, Compile method thusly:

            var @params = new CompilerParameters
            {
                GenerateInMemory = true,
                GenerateExecutable = false,
                IncludeDebugInformation = false,
                CompilerOptions = "/target:library /optimize",
                TreatWarningsAsErrors = false,
                WarningLevel = 0
            };

Although the default for TreatWarningsAsErrors is false in Mono, I think the default for WarningLevel is -1, which doesn't really mean anything. So this might actually be a Mono porting issue.