Forcing Browsers To Reload CSS & JS Files

One of the great features of web browsers is that they often cache files locally in order to avoid repeated requests to the web server for files whose contents rarely change.  This allows browsers to perform faster and avoid unnecessary bandwidth consumption.  CSS and JS files are wonderful caching candidates for these very reasons.  However, sometimes CSS and JS files ARE updated on a website, resulting in a need to force the browser to reload these files.  The question, then, is how can we accomplish this?

If you read my previous post, you saw that we can avoid a known AJAX caching issue in Internet Explorer by attaching a unique querystring parameter to the URL of each AJAX request.  It turns out that we can use this same strategy to force browsers to request the latest version of CSS and JS files as well.

For example, a typical CSS and JS reference in a web page looks like this.

<link href="/Content/MyApp.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/Scripts/MyApp.js"></script>

Typically, you’ll have these references on every page in your site. However, rather than request these files from the server for every page visited, browsers will cache these files after the first request and then fetch them from the cache for all pages afterwards. When faced with the need to update these files, we can force the browser to request the updated files from the server by changing the URL with a querystring parameter. This works because browsers cache pages by URL. Using the example above, we can force which files get reloaded using this strategy:

<link href="/Content/MyApp.css?ver=2" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/Scripts/MyApp.js?ver=2"></script>

As you can see, we added a ver=2 querystring parameter to each of the URLs. The first time a browser sees this new URL, it will discover that it doesn’t have an entry in its cache for this URL and will therefore request the file from the server (and then cache it). In this example, we can just increment the ver querystring parameter each time we have a new version of a file that we want to force browsers to load.

Keep in mind that it doesn’t matter what we use as the querystring parameter. We could have just as effectively used foo=bar to achieve the same result. In my work, I typically use ver=[date]. For example: ver=130130 (today’s date of Jan 30, 2013). Whatever convention you choose is really a matter of personal preference, for the end result is still the same. Just make sure that whatever approach you use doesn’t allow for a URL to ever be repeated or you’ll open up the possibility of a browser out there still having a cached copy of an older version of a file, resulting in the cached copy being used.

As Forrest Gump said, “that’s all I have to say about that”.

Please feel free to comment and share.

AJAX “GET” Not Calling URL In Internet Explorer

In my last post, I demonstrated the concepts of progressive enhancement and graceful degradation using AJAX as an example. In my example, I made use of the HTTP POST method in my AJAX request for the current time from the server. However, since I didn’t have any data to post to the server, you might be wondering why I didn’t just decide to make an HTTP GET request instead. The primary answer is a simple one: Internet Explorer caches the results of HTTP GET AJAX requests.

While using HTTP POST for all AJAX calls is one workaround to this problem, it assumes that you have the ability to modify the server code to accept HTTP POST rather than HTTP GET. In my work, whenever I’m developing server-side code, this is generally the approach that I take. However, in cases where you’re making an AJAX call to a third party service, this option is not likely available to you. For these situations, you can avoid IE caching by appending some extra data to the end of the URL that you change each time a call is made (such as a timestamp). The server will ignore these values, and although IE will cache the results, the results are cached by URL, meaning that each request will avoid a cache hit and will cause the URL to be called. If you’re using the JQuery ajax method, you can further simplify this process by instructing AJAX to not cache HTTP GET results (which behind the scenes causes ajax to append a timestamp to the URL as discussed above). You can learn more about this workaround in the JQuery ajax documentation.

So there you have it. Happy cache-free ajax-ing!

Progressive Enhancement & Graceful Degradation With Ajax

In the early days of the web, there was often a philosophy (and somewhat of a reality) that web sites/applications would look the same across all browsers.  This was because web content was written using a standardized language (HTML and CSS) to which all browsers would adhere.  Over time, however, newer versions of these specifications developed, with some browsers being quick to incorporate them while others lagged behind.  To further complicate this situation, JavaScript technology was introduced during this time to provide the ability to add dynamic behaviors to web pages.  The result of all these changes created a complicated target for web content creators that were, on one hand, looking to take advantage of the latest browser advances, while on the other hand, needed to have their content still function on legacy browsers.  The end result of these conflicting goals was usually the creation of multiple versions of the same content for different browsers or various CSS tricks and/or use of known browser loopholes or bugs.  Additionally, developers that made use of JavaScript in their web pages found themselves in similar situations as some browsers either didn’t support JavaScript, didn’t support it correctly or completely, or maybe had JavaScript disabled at the user’s request.

During this time, the community developed some best practices and strategies for addressing these complications, two of which are known as “progressive enhancement” and “graceful degradation”, which are really two sides of the same coin.  Progressive enhancement refers to the notion of starting with a lowest common denominator style and behavior that works across all browsers (or an agreed set of browsers) and then progressively “layering” advanced styles and behaviors in more advanced browsers.  This strategy allows developers to support users of older browsers without limiting the end-user experience for users of advanced browsers.

Graceful degradation is really just the opposite of progressive enhancement.  Using this strategy, developers will target the latest browser technologies first and then work backwards to find ways to support users of older browsers using techniques that allow the web application to still function, albeit with less appeal, through the use of older technologies.  The end-goal of both strategies is really the same: support as many browser/version scenarios as possible but without compromising the end-user experience for users of advanced browsers.

As with most everything, the best way to understand this is through example.  I’d like to focus on a simple scenario in which we want our application to work in browser environments in which JavaScript is either unsupported or disabled but then also take advantage of browser environments in which JavaScript is available (progressive enhancement).

Time Grabber 1

The Time Grabber web application is pretty simple. When the user clicks the button, the current UTC and local date and time will be displayed in the fields below the button. Looking at the HTML code, we can see that this app doesn’t require JavaScript to function since it’s just coded as an HTML form.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Time Grabber</title>
    <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
    ...

    <form action="/" method="post">
        <input id="btnGetTime" type="submit" value="Get current date/time" />
    </form>

    <p>UTC Time: <span id="utcTime"></span></p>
    <p>UTC Date: <span id="utcDate"></span></p>
    <p>Local Time: <span id="localTime"></span></p>
    <p>Local Date: <span id="localDate"></span></p>

    ...
</body>
</html>

When the user clicks the button, a post is made to the server and some server-side code produces the following response page.

Time Grabber 2

However, if JavaScript is available in the browser, we can avoid a form post and a page transition by using JavaScript/JQuery to make an AJAX call to the server to retrieve the current date/time information and then update the fields in the page using JavaScript/JQuery, as shown in the following code.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Time Grabber</title>
    <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
    <script src="/Scripts/modernizr-1.7.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#btnGetTime").click(function() {
                $.ajax({
                    url: "http://localhost:17039/",
                    type: "POST",
                    success: function(result, status, xhr) {
                        $("#utcTime").text(result.UTCTime);
                        $("#utcDate").text(result.UTCDate);
                        $("#localTime").text(result.LocalTime);
                        $("#localDate").text(result.LocalDate);
                    }
                });

                return false;
            });
        });
    </script>
</head>
<body>
    ...

    <form action="/" method="post">
        <input id="btnGetTime" type="submit" value="Get current date/time" />
    </form>

    <p>UTC Time: <span id="utcTime"></span></p>
    <p>UTC Date: <span id="utcDate"></span></p>
    <p>Local Time: <span id="localTime"></span></p>
    <p>Local Date: <span id="localDate"></span></p>

    ...
</body>
</html>

With this additional code, JavaScript-capable browsers will use a progressively enhanced method of retrieving the current date/time while JavaScript-incapable browsers will ignore the script tags in the HTML and just utilize a form post. Boom!

Depending on your knowledge of JQuery, you might be asking yourself how the JavaScript/JQuery code works. While a detailed explanation of this is a topic for another post, in short, it goes something like this:

As soon as the browser completes loading the content of the HTML page, JQuery will trigger the “ready” callback function. The first thing this callback function does is to register a callback function for the button’s click event. This function makes an AJAX call to the server using the “ajax” method, which takes parameters for the url, the method (GET or POST), and a callback function for a successful response (HTTP status code 200). The success callback function takes a few parameters, one of which is the content response from the server (which in this case is formatted as JSON). Inside this callback function, we simply update the values on the page with the values from the response. The final step of the click callback function is to return “false”. This prevents the browser from performing its default behavior to the button click event, which is to post to the server and load a new page. Done.

Whether this whole thing is a case of graceful degradation or progressive enhancement is really a matter of perspective and depends mostly on the developer’s initial goal: optimize for broadest support (progressive enhancement) or optimize for richest user experience (graceful degradation).

If you’d like to play around with the code used in this example, you can download the source code here.

If you found this post helpful or you have questions, please share and/or leave comments.

Designer view for EDMX file gone in Visual Studio 2010

I ran into this interesting little problem today and thought I’d share the solution for anyone else that runs into it as well…

In my Visual Studio 2010 project, I needed to make some modifications to the EDMX file being used by the Entity Framework to connect to the database. However, upon double-clicking the EDMX file, it was opened using the XML editor rather than the visual designer (called “ADO.NET Entity Data Model Designer”). Upon further investigation, it appeared that the visual designer was no longer even registered/installed as it didn’t appear in the list of “Open With…” editors (right-clicking the EDMX and selecting “Open With…”).

After doing some Googling, I found the following solution:

  1. On the Visual Studio 2010 installation DVD, browse to the “\WCU\EFTools” folder and copy its 2 files to your PC.
  2. In the folder where you copied the files, create a file named “Log.txt”.
  3. Open a cmd prompt (one that has administrative rights) and navigate to the folder with the copied files.
  4. Run the following command: ADONETEntityFrameworkTools_enu.msi USING_EXUIH=1 /log “Log.txt”.

The installation takes a while, but after it’s complete you should be able to use the EDMX designer again in Visual Studio 2010.

I have no idea how this problem happened on my PC. I recall having Visual Studio crash yesterday. Perhaps something freaked out along the way. Either way, I’m back in business and hopefully this information can quickly help get you back in business if you run into this problem as well!

Thanks to StackOverflow for hooking me up with the answer to this problem. Here’s the StackOverflow post where I found the solution to this problem.

Enjoy!

Tidbit: LINQ Error “Sequence contains no elements”

This generally happens when you attempt to use the First or Single method on the results of a query, such as:

    IQueryable query = /* some query */;
    var item = query.First();

If there are no results in the query, calls to the First method will generate this error. This is because the First method assumes that there will be at least one item in the result set.

If an empty result set is an expected scenario, use the FirstOrDefault method. This will return either the first item or the default value for the item type (which will vary depending on the item type) if the result set is empty.

Enjoy!

Uploading files in ASP.NET MVC

If you’ve tried creating a form that includes a file upload, you might have run into a problem of having a null value for the posted file in your controller’s action method. Take the following (Razor) view that accepts a string and a file upload as an example:

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(model => model.SomeString)
        @Html.TextBoxFor(model => model.SomeString)
    </div>
    <div>
        <label for="fileUpload">File upload</label>
        <input type="file" id="fileUpload" name="fileUpload" />
    </div>
    <div>
        <input type="submit" value="Submit" />
    </div>
}

Now, assume the following action method on your controller class:

[HttpPost]
public ActionResult Upload(string someString, HttpPostedFileBase fileUpload)
{
   // Here's where I do something interesting with the uploaded file.
}

When we run this code we’ll find that the fileUpload variable that’s passed into our controller method is null even though the someString value is populated as expected. Why?

One of the subtle things that we have to remember (and which I have forgotten on several occasions) with file upload forms is that we have to change enctype attribute of the form tag to “multipart/form-data” (incidentally, the default value is “application/x-www-form-urlencoded”). Oh yeah, now we remember! So, let’s just add that attribute to the form tag in our view code above. But wait. There’s no form tag in the view code above. It’s being rendered by the BeginForm helper method. So now what do we do?

It turns out that there’s an overloaded version of the BeginForm method that will allow us to do exactly what we need. The revised version of the view looks like this:

@using (Html.BeginForm("Upload", "MyControllerName", FormMethod.Post, new { enctype = "multipart/form-data"}))
{
    <div>
        @Html.LabelFor(model => model.SomeString)
        @Html.TextBoxFor(model => model.SomeString)
    </div>
    <div>
        <label for="fileUpload">File upload</label>
        <input type="file" id="fileUpload" name="fileUpload" />
    </div>
    <div>
        <input type="submit" value="Submit" />
    </div>
}

See the last value we’re passing to the BeginForm method call? That’s the key! This tells the BeginForm method that we want to add the specified attribute name/value to the form tag. Now when we run the code, the fileUpload value passed in to the controller method will be fine and dandy.

Enjoy!

Non-database data manipulation using LINQ and extensions

I’ve been using LINQ more and more over the last year or so, not just as a tool for accessing database data via Entity Framework, but also for manipulating non-database data and with much less coding than before. I ran into a good example of this today as I needed to remove some items from a collection.

In short, I needed to remove keys of a certain prefix from the ModelState of an ASP.NET MVC view. In the past, I might have done something like this:

string[] keys = ModelState.Keys.ToArray();
foreach(string key in keys)
{
    if (key.StartsWith("PrefixToBeMatched"))
    {
        ModelState.Remove(key);
    }
}

We basically iterate through the keys, find the ones that match our prefix, and then remove those that match our prefix. This isn’t exactly complicated code, but should serve as a good, simple example of how you can use LINQ to accomplish things in new ways and with less code.

Using LINQ, we can shorten the code to the following:

ModelState.Keys.Where(key => key.StartsWith("PrefixToBeMatched")).Select(key => ModelState.Remove(key));

Now we have just one line of code, which basically says “where a key from ModelState.Keys matches the prefix (the Where method), go ahead and remove it (the Select method).

Great, right? Well, it doesn’t work. The code executes fine, but nothing happens. Why?

With LINQ, you’re really building an expression (the “Where” method in this case), which in turn can have cascading expressions (the “Select” method in this case). However, these expressions aren’t actually executed until you request the results by assigning them to an object. Huh?

Most of the time, you’re using LINQ to fetch some data and then assign that data to something else, either for additional processing or for rendering to a UI. In those cases. you typically will convert the LINQ expression to another type via one of the many “To…” extension methods (ToList, ToDictionary, ToArray, etc.). It’s in these methods where the expression is actually executed and the results are assigned. This way, you can build a complex, chained set of expressions with no performance hit until the very moment that the results are assigned to something.

Going back to the earlier example, though, we see that we never assigned the results to anything. This is because this LINQ expression isn’t about retrieving data, but rather changing it (via the call to the ModelState.Remove method). So, if all we have to do is call one of the “To…” extension methods to retrieve the results, we should be in good shape…

ModelState.Keys.Where(key => key.StartsWith("PrefixToBeMatched")).Select(key => ModelState.Remove(key)).ToArray();

All we did was chain a call to ToArray at the very end of previous code. Since we didn’t really care about the results (but rather the action carried out), we didn’t assign the results to anything.

Now everything should be good, right? Well, not quite. Running this code will generate an error. This is because there’s one other subtle issue here that’s very specific to this scenario: we can’t remove items from a list that we’re currently iterating through. This is not a LINQ issue though. In fact, in the original code where we weren’t using LINQ, we would have faced the same problem if we had iterated through ModelState.Keys rather than the keys string array to which we copied the list of keys. So, it sounds like we need to do the same thing in our LINQ expression…

ModelState.Keys.Where(key => key.StartsWith("PrefixToBeMatched")).ToArray().Select(key => ModelState.Remove(key)).ToArray();

See where we inserted a call to ToArray between the Where and Select method calls? That does the trick!

We could stop here and be done. However, there’s something about having to assign the results of the Remove call to an object in order to get the expression to execute that just doesn’t feel right. One solution we could implement is to write an extension method called Execute that we could use in place of the Select method and then have that method carry out executing the expression for us. This also makes intuitive sense and also makes the code read better. The extension method looks like this:

public static void Execute<T>(this IEnumerable<T> list, Action<T> action)
{
    foreach(T item in list)
    {
        action(item);
    }
}

By executing the action (calling action(item)), we cause the expression to execute the same way that we did by calling ToArray earlier. With this extension now available, our key manipulation code can be revised to look like this:

ModelState.Keys.Where(key => key.StartsWith("PrefixToBeMatched")).ToArray().Execute(key => ModelState.Remove(key));

With this example, we demonstrated how to use LINQ and extensions to reduce and simplify non-database data manipulation. Plus, we created a new extension method that can be re-used for other similar data manipulation scenarios.

Enjoy!