MVC Controller Action called multiple times per page load.

Today I came across a real time sink of a gotcha with my MVC site. So I thought I’d share this on a post.

The issue
A standard Mvc controller action was getting called multiple times each time a GET request was made in the browser. Sometimes twice, sometimes once, and occasionally more.

Opening up Chrome dev tools to try and understand the problem, I spotted the multiple requests in the Network tab. Interstingly when I filtered by type the additional requests were showing up in the Images tab. Looking at the media type, the requests were being made the following acceptt header

image/webp,image/*,*/*

The initiator column pointed to javascript being the culprit.

chrome-dev-tools

However, this was a red herring. After a lot of code removal, view in browser, rinsing and repeating, I isolated it to the following line

<div id="hero" style="background-image: url('@Model')">

The cause
It took a while for the penny to drop, but the problem occurred when the Model was an empty string. So with nothing passed to the url property, the background image was requesting controller once the markup rendered. This was happening in a number of places in the page. So the controller was being called as many as four times each time the page was loaded.

I only tested this in Chrome, so the behaviour may not be the same across a other browsers.

The solution
As this markup was in a number of places across the site, I created an Html Helper extension, which simply checks to see if the string is null or empty.

My markup now looks like this

<section class="pageHero compactHero bottomAligned" @Html.StyleAttributeForHeroImage(Model.BackgroundImage)>

And the Helper looks like this;

public static class StyleAttributeExtensions
{
    public static MvcHtmlString StyleAttributeForHeroImage(this HtmlHelper helper, string imageUrl)
    {
        var styleAttribute = String.Format("style=\"background-image: url('{0}')\"", imageUrl);

        if (String.IsNullOrWhiteSpace(imageUrl))
        {
            styleAttribute = String.Empty;
        }
        return MvcHtmlString.Create(styleAttribute);

    }
}

So now I only have one request per controller action when each pages loads. This has resulted in a noticeable improvement in page load times.

Hope this helps someone else out.

Using GhostScriptSharp to create pdf thumbnails

It sounds like a simple task. Creating thumbnails of uploaded files for display in a repeating list. The project I am working on uses Kentico CMS, which provides the majority of this functionality out of the box. However, it did not create thumbnails for pdf files. The interim solution was to display the default pdf file icon. This worked for the first few weeks after which it became clear that the majority of the uploaded documents were pdf’s. This made for a very uniteresting screen, so the decision was made to find a component or service to create pdf thumbnails.

After a little research I decided on GhostscriptSharp, a C# wrapper for the GhostScript library. Installed, up and running, and simple solution implemented beautifully on localhost within a couple of hours. And so to the Staging staging server…. a very different server. This did not take hours or sadly days, but a couple of weeks (albeit of on and off development) to get working.
I am now going to outline the major time-sinks I encountered when getting GhostscriptSharp working on a remote staging server;
Firstly, you do not need to install GhostScript on the server which your code is running. This is something that was not 100% clear from the documentation. I was also hampered by the suggestion from several other blog posts that this was indeed a prerequisite for getting GhostScriptSharp up and running. For me, this was simply not the case. Your application will only require the correct version (I’ll come to this later!) of the GhostScript dll in it’s bin folder.
The next problem I encountered was the following error message;
Message: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) Stack Trace: at GhostscriptSharp.GhostscriptWrapper.CreateAPIInstance(IntPtr& pinstance, IntPtr caller_handle)
My working solution was developed on a 64-bit machine. I was deploying to a 32bit machine. There are two versions of GhostScript a 64 bit and a 32 bit version (can you see where I’m going here?).
So, if you see this error message with your GhostScript application, check you are using the correct version of the dll.
Correct dll in the bin folder. Show me the pdf thumbnails.
No?
Another error message was now being displayed by my application. This one said;
Unable to load DLL ‘gsdll32.dll’: The specified module could not be found.

This error message was caused by insufficient permissions on the bin folder. To overcome this I had to grant read & write permissions for the application pool identity on the /bin folder to enable it to access the dll.


Another error message bites the dust, surely now…. thumbnails? No. Though now my application was up and running, so no more asp.net error messages, just application error messages. This one said;

Ghostscript 100 error

As it so often does, Stackoverflow came to the rescue. As well as granting read and write permissions on the bin folder, I also had to grant read and write permissions on the /files folder (the folder my thumbnails were being written to). This allowed the GhostScript dll to write thumbnails to the specified location.

And with that final change, the application sprang in to life and several hundred thumbnails were written to disk. Ah, the taste of victory.


In summary, writing the GhostScriptSharp code was a really simple process. Getting it to run on a production server was a slightly more involved process, but I would definitely use it again on other projects with the configuration knowledge I now have in the bank.