Serializing/Deserializing Objects Using XML

Occasionally you run across the need to store object information to persistent storage.  Many times that persistent storage takes the form of a database.  However, not all applications make use of databases.  In these cases, persistent storage is usually accomplished using the file system.

There are multiple methods for storing object information on the file system, each of which has different levels of built-in support in the .NET Framework.  One method is to use .NET’s configuration API (app.config, web.config).  Although this API provides a great deal of built-in configuration support, configuration files are read-only and therefore may not be the right solution for your needs.

Another method is to write your own code to create, read, update, and delete either text or binary files using a format of your own choosing.  This will give you the most flexibility, but does so at the expense of leaving you to write and test more code.

A third method, and the one that is the topic of this post, is to use .NET’s XML API, specifically the XMLSerializer class.  Using this class, we can take a standard C# object and write (or serialize) it to the file system as an XML document.  We can also go in reverse, reading the XML document from the file system and generating an instance of the original object and its state.

I recently came across the need for such an approach while working on a game that I’m developing with my kids.  If you’ve played PC games, you know that most of them have a settings screen where you can re-map game commands to different keyboard keys and have those new mappings persist without having to set them each time the game is run.  This seemed like a perfect use case for the XMLSerializer class.

There are two basic tasks involved with serializing/deserializing objects using XML.  The first task is that we need to define a class, an instance of which we intend to serialize/deserialize.  In my case, I defined a KeyboardMappingsConfig class, as shown below.

    /// <summary>
    /// Provides object schema definition for serializing/deserializing keyboard mappings to/from configuration file.
    /// </summary>
    [XmlRoot("KeyboardMappings")]
    public class KeyboardMappingsConfig
    {
        /// <summary>
        /// Key mapped to the Escape control command.
        /// </summary>
        public Keys Escape { get; set; }

        /// <summary>
        /// Key mapped to the Console control command.
        /// </summary>
        public Keys Console { get; set; }

        /// <summary>
        /// Key mapped to the ListPlayers control command.
        /// </summary>
        public Keys ListPlayers { get; set; }

        /// <summary>
        /// Key mapped to the Forward control command.
        /// </summary>
        public Keys Forward { get; set; }

        /// <summary>
        /// Key mapped to the Back control command.
        /// </summary>
        public Keys Back { get; set; }

        /// <summary>
        /// Key mapped to the Left control command.
        /// </summary>
        public Keys Left { get; set; }

        /// <summary>
        /// Key mapped to the Right control command.
        /// </summary>
        public Keys Right { get; set; }

        /// <summary>
        /// Key mapped to the Up control command.
        /// </summary>
        public Keys Up { get; set; }

        /// <summary>
        /// Key mapped to the Down control command.
        /// </summary>
        public Keys Down { get; set; }
    }

As you can see, there’s nothing very special about this class.  Although my class doesn’t have any methods assigned to it, there is nothing preventing you from adding methods to it.  The main thing is that any properties that you want to read/write from/to XML must have public getters and setters.  This is because the XMLSerializer class scans the object to determine which values to write to XML via the getters and populates a new instance of the object when reading from the XML via the setters.  Notice also the XmlRoot attribute on the class declaration.  We’ll come back to that in a later post, but for now you should know that various attributes can be used on the class and property declarations to override the default behavior of how the XmlSerializer class serializes/deserializes.

Once we have the to-be-serialized class defined, the second task is to write the code to serialize/deserialize the class using the XMLSerializer, starting with the code shown below.

string settingsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyGame");
string keyboardMappingsConfigPath = Path.Combine(settingsFolder, "KeyboardMappings.xml");

if (Directory.Exists(settingsFolder) == false)
{
    Directory.CreateDirectory(settingsFolder);
}

XmlSerializer serializer = new XmlSerializer(typeof(KeyboardMappingsConfig));
using (StreamWriter writer = new StreamWriter(keyboardMappingsConfigPath))
{
    serializer.Serialize(writer.BaseStream, keyboardMappingsConfig);
}

The first few lines of code check to see if the folder that we’re using to store the XML files already exists, and create it if it doesn’t.  Further down, we create a XmlSerializer object, whose constructor takes the type of class to be serialized (KeyboardMappingsConfig in our case).  This allows the XmlSerializer object to know what type of class it is dealing with when serializing.  Next we create a StreamWriter (giving it the path to use) and call the XmlSerializer’s Serialize method using the StreamWriter and an instance of the KeyboardMappingsConfig class (previously instantiated and populated outside of this code section).  After this code runs, there should be a file called KeyboardMappings.xml on the file system at the specified location, the contents of which should look similar to that shown below.

<?xml version="1.0"?>
<KeyboardMappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Escape>Escape</Escape>
  <Console>T</Console>
  <ListPlayers>Tab</ListPlayers>
  <Forward>W</Forward>
  <Back>S</Back>
  <Left>A</Left>
  <Right>D</Right>
  <Up>Space</Up>
  <Down>LeftShift</Down>
</KeyboardMappings>

Now that we’ve serialized our object to XML, let’s try to deserialize it.  As you probably expect, the process is pretty much the reverse of what we did above, as shown below.

string keyboardMappingsConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyGame", "KeyboardMappings.xml");
KeyboardMappingsConfig keyboardMappingsConfig = null;

XmlSerializer serializer = new XmlSerializer(typeof(KeyboardMappingsConfig));
if (File.Exists(keyboardMappingsConfigPath) == true)
{
    using (StreamReader reader = new StreamReader(keyboardMappingsConfigPath))
    {
        keyboardMappingsConfig = (KeyboardMappingsConfig)serializer.Deserialize(reader);
    }
}

Similar to before, the first line is for specifying the file path/name.  Next, we create a KeyboardMappingsConfig object reference (the class we defined earlier), followed by the creation of a XmlSerializer object, whose constructor (as before) takes the type of class to be deserialized.  Next, we check to see if the file already exists.  Assuming it does, we load it into a StreamReader and pass the StreamReader to the XmlSerializer’s Deserialize method, the result of which we need to cast to our KeyboardMappingsConfig class.  After this code runs, we should have an instance of the KeyboardMappings class whose values match those in the XML file.

Pretty darn simple!

That’s it for now.  In the next post, we’ll dig into some more advanced aspects of the XmlSerializer class using attributes to override and customize its default behavior.  Until then, happy serializing!

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!