.NET MVC3: Prevent 404 for missing CSS files? Or ensure files exist before writing HTML?

476 Views Asked by At

We have a requirement to provide skinning capabilities to an ASP.NET MVC3 app.

My approach so far has been to tackle this with a cookie and child actions for the css files:

  1. Client links to our app using a URL like www.ourapp.com/as/www.clientapp.com/then-go-to/path/in/ourapp.
  2. The above url is routed to an action method that writes a cookie named "skin" with value "www.clientapp.com" and then redirects to /path/in/ourapp.
  3. Our layout (masterpage) has an @Html.Action in the <head> section where the css files are to be rendered.
  4. The child action inspects the cookie and creates a viewmodel that will tell the partial view which <link> tags to render.

The css file structure is based on the cookie value. So our css content might look like this:

/content
    /www.clientapp.com
        /style1.css
        /style1.css
    /www.client2app.com
        /style1.css
        /style2.css

I am open to hearing better patterns / alternatives to the above for applying skins to the layout. However this isn't the reason for my question.

There is currently a problem with this approach when the css files are not present in the filesystem. The request causes IIS to return a 404. We override the 404 page with a custom page (not using the same layout that has the @Html.Action in the <head>). This causes IIS to do some additional processing which is not necessary (for example partials & child actions to render sign-in/sign out links, horizontal nav, etc, on the 404 page's layout).

The way I see it there are 2 ways to solve this:

  1. In the child action that configures the css, check to make sure the files exist on disk before telling the viewmodel that they should be rendered. Pro with this approach is that it should be fairly easy. Cons are that to unit test it, would have to wrap file I/O in a service that can be injected. Also the app will be deployed to Azure. I think Azure can read the filesystem (which is what would be needed), but not write to it.
  2. Somehow prevent a 404 from being returned for css files. To do this, would we have to implement logic in global.asax Application_Error? Or is there another way to prevent missing CSS files from triggering a 404 response?

Which approach is correct? Or is there another that I'm not considering?

Update

We ended up solving this in the custom 404 error page like so:

[ActionName("not-found")]
public virtual ActionResult NotFound()
{
    // do not return 404 for missing css files
    if (Request.RawUrl.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
    {
        Response.StatusCode = 404;
        return new EmptyResult();
    }
    return View();
}
1

There are 1 best solutions below

0
On BEST ANSWER

One option would be to not override 404 errors for CSS requests.

For missing CSS files, return the 404 status, but leave the body empty. The body doesn't matter with a CSS file, since a human doesn't see it, and all the browser cares about is the status.