Monthly Archives: October 2012

JSON with ASP.NET MVC 4

As a newcomer to JavaScript and jQuery, I wanted to write a (supposedly) simple little web site which used JSON (JavaScript Object Notation) to transmit information from a database to a web page. Surprisingly there didn’t seem to be any self-contained example or tutorial (that I could find) that showed how to do this basic operation. So here is the result of my attempt. It turns out that it is actually quite simple, once you know what to do.

First off, what is JSON? It is an alternative to XML as a way of sending information from one device to another. It’s a subset of the notation that can be used in JavaScript to define an object literal, which we saw in the last post. As an example, we might have some information on the numbers of various titles of comic books that are stored in a database. After we’ve retrieved this data from the database, we can encode it into JSON, so that it looks like this:

[
  {"Title":"Batman","Count":1},
  {"Title":"Fantastic Four","Count":2},
  {"Title":"Spider-man","Count":2},
  {"Title":"Superman","Count":1},
  {"Title":"Thor","Count":2}
]

That is, the data are stored as name-value pairs. In this case, each element in the array is actually a compound object consisting of two name-value pairs (Title and Count). We could have a simple list of single name-value pairs, or we could have deeper nesting of objects. There are various restrictions on the syntax for JSON objects, but as we’ll see, in MVC 4 you won’t usually have to write your own JSON, since there is a library routine that does it for you.

Now that we know what JSON is, how do we use it as a mediator between a database and a web page in ASP.NET MVC 4? We’ve seen that the procedure for generating web pages in MVC is as follows.

  1. Write a controller that contains a method that is called when a client requests a web page from the server.
  2. Write a view that is linked to the controller method, and which generates the markup that is returned to the client.

The controller method will usually collect some data from some other source, such as a database or some other C# code (which is usually part of the Model in MVC). This data is then packaged up, possibly in a C# object, and sent to the View, where the View formats the data and generates the HTML which is interpreted by the browser.

The procedure for using JSON doesn’t quite fit this pattern. Basically what happens is this:

  1. Client requests a web page.
  2. Controller method is called to process this request.
  3. The corresponding View is returned to the browser.
  4. The View contains some JavaScript code that makes another request to the server, this time asking for some data in JSON format.
  5. different Controller method from that called in step 2 is called to generate the JSON, which is returned to the browser.
  6. The JavaScript code processes the JSON and generates some HTML which is displayed.

The key point is that the JSON is not meant to be displayed as raw data by the browser; rather, it is retrieved by the browser and then processed on the client side before it is displayed.

We’ll illustrate this by showing how the data above can be obtained from the database and sent to a web page using JSON. First, we’ll add a controller to our ComicShop project that we’ve been using to demostrate things:

using System.Web.Mvc;
using ComicShop.Models;
using System.Collections.Generic;

namespace ComicShop.Controllers
{
  public class JsonController : Controller
  {
    //
    // GET: /Json/

    public ActionResult Index()
    {
      return View();
    }

    private IComicRepository comicRepository;

    public JsonController()
    {
      comicRepository = new ComicRepository();
    }

    public JsonController(IComicRepository comicRepository)
    {
      this.comicRepository = comicRepository;
    }

    public ViewResult JsonSummary()
    {
      return View();
    }

    public ActionResult Summary()
    {
      IEnumerable<ComicSummary> summaries = comicRepository.GetSummaries();
      return Json(summaries, JsonRequestBehavior.AllowGet);
    }

  }
}

This controller uses the IComicRepository interface and ComicRepository class that we introduced earlier. This controller contains two methods of interest here. The one called JsonSummary() simply returns a View, which is the View that requests the JSON data (we’ll get to this View in a moment).

The Summary() method is the one that produces the JSON data. The first line in this method requests the data from the database (see the earlier post for details of how this is done; all that’s important here is that we do get this data). The data is returned as an IEnumerable<ComicSummary> list. The ComicSummary class is defined as:

namespace ComicShop.Models
{
  public class ComicSummary
  {
    public string Title { get; set; }
    public int Count { get; set; }
  }
}

That is, it contains two data fields named Title and Count.

The second line in Summary() calls the library method Json() to create the JSON data. It is passed the list of ComicSummary objects in the variable summaries. The second parameter allows Summary() to provide JSON data in response to an HTTP Get request (by default, such a response is blocked for security reasons, so this parameter is needed). This returns the JSON string we gave above.

That’s all there is to producing JSON data (as promised, you didn’t have to actually write any raw JSON yourself, since the Json() method does it for you). If you want to verify that Summary() actually works, you can call it directly from a web browser by using the URL http://localhost:36195/Json/Summary (the port number for your localhost server will probably be different; what’s important is the path /Json/Summary), and you should see the raw JSON data printed in the browser.

Note that we did not associate a View with the Summary() controller method. As far as the browser is concerned, it is receiving raw text as a response to its request to Summary, so it just displays that. We need to do something special if we want it to interpret the JSON as data and incorporate it into a ‘real’ web page.

To that end, we turn our attention to the JsonSummary() controller method, and have a look at its View. This is in the file JsonSummary.cshtml:

<h2>JsonSummary</h2>
<script>
    $.getJSON('/Json/Summary',  function (data) {
        var items = [];
        $.each(data, function (key, val) {
            items.push('<li>' + key + ': ' + val.Title + ' (' + val.Count + ')</li>');
        });

        $('<ul/>', {
            html: items.join('')
        }).appendTo('body');
    });
</script>

As you can see, most of this file is JavaScript. However, it’s not all primitive JavaScript; it makes use of jQuery, so you need to make sure your web project has jQuery installed. If you started with an Empty project, you’ll need to do this yourself; if you started with a full Internet project, it will already be included.

To add in jQuery, right-click on the Solution in SolutionExplorer and select Manage NuGet Packages. Search in the Online section and find jQuery, then click Install. JSON should already be installed – you can check this by opening up References in SolutionExplorer and seeing that Newtonsoft.Json  is included in the list.

NuGet should take care of installing these packages and should find some jQuery JavaScript files in your Scripts folder (if you didn’t have a Scripts folder, it will be created by the installation).

We’re not quite done yet, though. In order for jQuery to be used in your View, that View needs to run the jQuery script. You could include a <script> tag in the View file itself, but if you plan on using jQuery in a lot of Views, it makes more sense to put it in the common layout file which we considered earlier. This file is called _Layout.cshtml and is in the Shared folder within the Views folder. Add the call to the jquery script in the <head> section of the layout. The modified _Layout.cshtml file looks like this:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <script src="~/Scripts/jquery-1.8.2.js"></script>
    <meta name="viewport" content="width=device-width" />
    <title>Comics</title>
</head>
<body>
    <h2>Comic Shop</h2>
    <div>
        @RenderBody()
    </div>
</body>
</html>

The call to the script is on line 9. The actual version number of jquery may differ from 1.8.2 if you install it later on, but just insert whatever version you got from NuGet.

That’s all we need to get the JavaScript to run, but there’s one more thing that’s very useful, and that’s to get Intellisense working for jQuery. Complete instructions for doing this are here, provided you’re using VS 2012. My _references.js file looks like this:

/// <reference path="jquery-1.8.2.intellisense.js" />
/// <reference path="jquery-1.8.2.js" />

Right, now we can look (finally) at JsonSummary.cshtml. A lot of the code there relies on a knowledge of JavaScript and jQuery syntax, so I won’t go through it in detail. However, I’ll mention a few key points so you can adapt it for your own purposes.

First, the $.getJSON() call is a jQuery method which makes a request to the URL given as its first argument for some JSON data. In our case, we use a relative URL /Json/Summary (the leading / is important: don’t leave it out!). If this call is successful, the JavaScript function given as the second argument to $.getJSON is called. (If the call fails, this function isn’t called, and you’ll get nothing on your web page apart from the HTML that is outside the <script> tag. This can make debugging a nightmare, since you won’t know what’s wrong, but never mind.)

The argument ‘data’ sent to this function is the JSON code. This function then constructs an array called ‘items’ by iterating through ‘data’ using the jQuery $.each() method. The second argument to $.each() is another function, this time taking two arguments. The ‘key’ argument is the integer index of the element from ‘data’ that is being processed, and ‘val’ is that actual element from ‘data’. Remember from the JSON above that each element in ‘data’ is a compound object of type ComicSummary, so it contains a Title and a Count field. We access these fields to create a HTML list entry on line 6, and push this onto the items array.

The last bit of code on lines 9 to 11 creates a <ul> tag and adds the items list to it, then it adds the <ul> tag to the body of the page. The final result looks like this:

JavaScript objects

After many years as an OO programmer using primarily C++, Java and C#, I’m finally taking a first look at JavaScript. At the lower syntax level, that of most operators, expressions, if statements and loops, JavaScript is much like other OO languages such as C# and Java. Above that level, things diverge quite rapidly. I’ll have a look at how JavaScript handles objects (in the OO sense) here.

One of the big differences between JavaScript and other mainstream OO languages (I’ll use C# as the main point of comparison from here on, as it’s the language I’m using for most other stuff) is that JavaScript is an untyped language. That is, you don’t need to (in fact, you can’t) specify the data type of a variable when it is declared. JavaScript has the ‘var’ keyword which should be used when declaring a variable. (I say ‘should be used’ since it is possible to declare a variable without using ‘var’, but this effectively makes the variable global, which is usually undesirable, so it’s best not to do it.)

However, JavaScript’s var is not the same as C#’s var. In C#, once a variable has been declared using var (or indeed, declared using any method), the data type of that variable is fixed. In the case of C#’s var, the data type is determined by the object to which that variable is initialized. In JavaScript, the data type of a variable is mutable, so you can, for example, declare a variable and assign a string to it, and later assign a different type such as a number. JavaScript is therefore loosely typed.

Another difference is that although objects are used in JavaScript, classes are not. This might seem contradictory; how can you have an object if it’s not an instance of a class? In this sense, JavaScript objects are similar to anonymous types in C#. An object can be created by simply listing some name-value pairs. For example, if we wanted an object that represents a book, we could write:

var bookObj = {
  author: "Delaney",
  title: "Nova",
  price: 5.47
}

This form of object is called an object literal, since it is a literal description of what one particular object contains. We could then use this object in a browser page by writing (assuming that the above code is stored in the file /Scripts/ObjectTest.js relative to the home page):

<h2>Books</h2>
<script src="~/Scripts/ObjectTest.js"></script>
<script>
    document.writeln(bookObj.author + ': <i>' + bookObj.title + '</i>  £' + bookObj.price + "<br>");
</script>

(We could, of course, have put the document.writeln() statement in the file as well, but this way we can see how to use the results of the first script in a script within the browser.)

This method is fine if we’re content to create single objects, but one of the powers of traditional OO languages is the ability to define a new data type (the class) and then create a number of objects of that data type. How do we do that in JavaScript?

It turns out that although JavaScript doesn’t have a class as such, it has a structure that, in practice, is very close to one, at least in the way it can be used. A class can be simulated in JavaScript by using a function.

A JavaScript function is actually an object in the same way that the untyped object above is. That is, a function can be created and passed around the program like any other object. In this sense, JavaScript functions are similar to C# delegates.

All objects in JavaScript have a prototype object behind them. This has a number of implications which we’ll get to in due course, but for now we can think of it as a form of inheritance. Just as all C# classes by default inherit the ‘object’ class, all object literals like the example above are backed by the Object.prototype object.

All functions are backed by Function.prototype, but each individual function also has its own prototype object behind it. This prototype can be used to add methods to a function.

Functions have a wide variety of uses, which we’ll get to in due course, but for now, the one we are interested in is the constructor function. This looks a lot like a class definition in C#. Here’s a constructor for a Book object:

var Book = function (author, title, price) {
  this.author = author;
  this.title = title;
  this.price = price;
};

Book.prototype.description = function () {
  return this.author + ': <i>' + this.title + '</i>  £' + this.price;
}

var book1 = new Book("Asimov", "Foundation", 3.55);
var book2 = new Book("Adams", "Hitchhiker's Guide to the Galaxy", 4.95);

The first 5 lines declare the constructor function, and define three data fields within it. All functions begin with the keyword ‘function’, followed by an argument list (which can be empty). As JavaScript doesn’t impose data types on its variables, this argument list contains no types, just parameter names.

The body of the constructor makes use of the keyword ‘this’. As in C#, ‘this’ refers to the object which called the function, so here, ‘this’ refers to the Book object that is being created. This code should look very similar to a constructor in C#.

Line 7 shows how to add a method to a Book object. We access the hidden prototype of the Book constructor, and then append the method name, which is ‘description’ here. The prototype is allowed to refer to ‘this’ in the same way as the original constructor. Here we just return a string containing some HTML to render the Book’s data in a browser.

The last two lines show how we can use the Book constructor to create a couple of objects. Again, these declarations look very similar to those in C#.

To use this code in a browser, we could put the following in the HTML file for the web page:

<h2>Books</h2>
<script src="~/Scripts/ObjectTest.js"></script>
<script>
    document.writeln(book1.description() + "<br>");
    document.writeln(book2.description() + "<br>");
</script>

Running the script from the file creates the book1 and book2 objects, and we can just call the description() method on them to obtain the HTML to render on the web page.

There are other ways of achieving the same result, but this little example should illustrate how JavaScript handles objects and object creation.

LINQ to XML: Creating an XElement

In the last post, we showed how to create a simple XML document in which the data were entered from a DataGrid. We gave the code for constructing the XML as follows:

    private XElement XmlFromLibrary()
    {
      ObservableCollection<Book> library = (ObservableCollection<Book>)((ObjectDataProvider)FindResource("LibraryGrid")).Data;
      XElement libraryElement =
        new XElement("LIBRARY",
          library.Select(book =>
            new XElement("BOOK",
              new XElement("AUTHOR", book.Author),
              new XElement("TITLE", book.Title),
              new XElement("PRICE", book.Price))));
      return libraryElement;
    }

The ‘library’ is fetched from a Windows resource defined in the XAML, with this resource being bound to the DataGrid (see earlier post for full details).

In writing this code, we glossed over some of the details of how the XElement is built. In fact, we used several techniques in this code that could do with further explanation.

The basic form of an XElement constructor is

XElement(XName name, params object[] content);

The first parameter gives the name of the XElement, which is used as the tag when writing out the XML. Usually, we’ll just enter a string here, and rely on the fact that the XElement constructor will convert this into an XName internally so we don’t need to worry about it.

The second parameter uses C#’s params keyword, which allows a variable number (one or more) of arguments to be passed to the constructor. As the data type of the content is just ‘object’, any data type  can be passed as the content of an XElement, and it’s here that the richness of the XElement class comes into play.

There are 8 specific data types that are handled in special ways when passed in as the content.

  1. A string is, as you might expect, just used as is as the content of the XML tag. (In fact, a string is converted into an XText object before it is used.)
  2. XText: This is a special class which is added as a child node of the XElement, but its value, which is a string, is used as the XElement’s text content.
  3. XCData: This allows insertion of the XML CData type, which consists of unparsed character data. Such strings may contain characters such as > and &, which ordinarily have a special meaning in XML syntax, but would be ignored here.
  4. XElement: The content can be another XElement, which is added as a child node to the parent XElement.
  5. XAttribute: This object is added as a child node, and represents an attribute of the parent node.
  6. XComment: Allows a comment to be attached to the XElement.
  7. IProcessingInstruction: Allows a processing instruction to be added to the XElement. (You don’t need to worry about these for most XML that you’ll write, but I may get back to them at some point.)
  8. IEnumerable: This is the magic data type, since it allows collections of data, such as those produced by LINQ query operations, to be passed in as content. The elements in the collection are iterated over, and each element is treated as a separate parameter. We used this feature in the code above to insert a list of Book objects into the XML using a LINQ Select() call.

In addition, you can also pass a null as the content (which does have its uses, though we won’t go into that here).

Finally, if the content is any other data type, the XElement will call the ToString() for that data type and use that as the content. This can cause some confusion, since there are some other LINQ to XML classes (such as XDocument) that are used to attach properties to the XML file that will be accepted as content for XElement, but rather than having the expected effect, XElement will just call its ToString() method and use that as content.

As a simple example, here’s some code that creates an XElement using most of the data types above as content:

using System;
using System.Xml.Linq;

namespace LinqXml03
{
  class Program
  {
    static void Main(string[] args)
    {
      XElement document = new XElement("Library",
        new XComment("This is a test library"),
        new XElement("Program", new Program()),
        new XElement("Book",
          new XElement("Author", "Isaac Asimov"),
          new XElement("Title", "I, Robot"),
          new XAttribute("Pages", 357)),
        new XElement("Book",
          new XElement("Author", "Samuel R. Delaney"),
          new XElement("Title", "Nova"),
          new XAttribute("Pages", 293)),
        new XCData("This contains a > and a & character"),
        new XText("This also contains a > and a & character"));
      Console.WriteLine(document);
   }
  }
}

This produces the output:

<Library>
  <!--This is a test library-->
  <Program>LinqXml03.Program</Program>
  <Book Pages="357">
    <Author>Isaac Asimov</Author>
    <Title>I, Robot</Title>
  </Book>
  <Book Pages="293">
    <Author>Samuel R. Delaney</Author>
    <Title>Nova</Title>
  </Book><![CDATA[This contains a > and a & character]]>This also contains a &gt; and a &amp; character</Library>

The top level XElement has the name ‘Library’. Its first content is a comment, which is written with the <!–…–> delimiters. Next, we’ve added a content object of type Program (that is, the class in which this program is written). The output is produced as a normal XElement tag, but the ToString() method is called from the Program class since it’s not one of the data types that has special meaning as an XElement content. The default ToString() method for a class just produces that class’s full pathname, which in this case is LinqXml03.Program.

Next, we add a couple of Book elements, each of which contains a couple of other XElements for the author and title. We’ve also added an XAttribute for the number of pages in the book.

The last two lines demonstrate the difference between XCData and XText. The XCData reproduces the given text exactly, and encloses it within the <![…]]> delimiters used for CData. The XText places the text as the content of the Library tag, and translates special characters into the XML code, so that > become &gt; and & becomes &amp;.

We’ve already seen an example of using IEnumerable in the code fragment at the top of this post.

LINQ for XML – the basics

LINQ provides a library of classes and methods that allow XML to be generated and imported quite easily (certainly more easily than with previous .NET libraries).

We’ll assume the reader is familiar with the basics of XML syntax and dive in with a simple little program that allows the user to enter some details for books in a library, then store this data to a disk file as XML (and of course to read in data from an XML file and display it).

The GUI is a WPF DataGrid and a menu for handling file operations, as shown:

We’ll represent the data internally using a Book class to represent each book, and an ObservableCollection to represent the collection of books. The data structures are similar to those that we used in discussing data binding to lists and combo boxes. The Book class is a bit simpler than it was there:

using System.ComponentModel;
namespace LinqXml02
{
  public class Book : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;
    protected void Notify(string propName)
    {
      if (this.PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
      }
    }

    string author;

    public string Author
    {
      get { return author; }
      set
      {
        author = value;
        Notify("Author");
      }
    }

    string title;

    public string Title
    {
      get { return title; }
      set
      {
        title = value;
        Notify("Title");
      }
    }

    decimal price;

    public decimal Price
    {
      get { return price; }
      set
      {
        price = value;
        Notify("Price");
      }
    }

    public Book() { }
    public Book(string author, string title, decimal price)
    {
      this.author = author;
      this.title = title;
      this.price = price;
    }
  }
}

The ObservableCollection is created in a special class called Library:

using System;
using System.Collections.ObjectModel;

namespace LinqXml02
{
  public class Library
  {
    Random rand = new Random();
    private decimal BookPrice()
    {
      decimal price = rand.Next(0, 5000) / 100m;
      return price;
    }

    public ObservableCollection<Book> GetLibrary()
    {
      ObservableCollection<Book> library = new ObservableCollection<Book>();
      return library;
    }
  }
}

This class serves as a resource in the XAML file:

<Window x:Class="LinqXml02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:LinqXml02"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider x:Key="LibraryGrid"
                            ObjectType="{x:Type local:Library}"
                            MethodName="GetLibrary"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource LibraryGrid}" HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Menu VerticalAlignment="Top">
            <MenuItem Header="_File">
                <MenuItem x:Name="saveMenuItem" Header="_Save" HorizontalAlignment="Left" Width="145" Click="saveMenuItem_Click"/>
                <MenuItem x:Name="saveAsMenuItem" Header="Save _as" HorizontalAlignment="Left" Width="145" Click="saveAsMenuItem_Click"/>
                <MenuItem x:Name="openMenuItem" Header="_Open" HorizontalAlignment="Left" Width="145" Click="openMenuItem_Click"/>
                <Separator HorizontalAlignment="Left" Width="145"/>
                <MenuItem x:Name="exitMenuItem" Header="E_xit" HorizontalAlignment="Left" Width="145" Click="exitMenuItem_Click"/>
            </MenuItem>
        </Menu>
        <DataGrid x:Name="bookGrid" Grid.Row="1" ItemsSource="{Binding}" AutoGenerateColumns="False"  HorizontalAlignment="Stretch">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Author" Binding="{Binding Author}" Width="45*"/>
                <DataGridTextColumn Header="Title" Binding="{Binding Title}"  Width="45*"/>
                <DataGridTextColumn Header="Price" Binding="{Binding Price}"  Width="10*"/>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>

On lines 7 to 9 we create the resource, then use it as the data context for the Grid on line 11. The DataGrid defined on line 25 uses this data context as the binding for its ItemsSource property, and then we define the three columns, each bound to a property in the Book class. We could have used the auto-generate column feature of a DataGrid, but that doesn’t allow us to customize the widths of the columns, which we’ve done here by assigning each of the Author and Title columns 45% of the horizontal width, with Price getting the remaining 10%.

With the data structures set up and the binding in place, we could run the program and enter some book data, and the data binding will automatically update the ObservableCollection as we enter data into the DataGrid. However, at this stage we have no way of saving the data thus entered. For that we introduce the XML.

First, we’ll have a look at the event handlers for the Save and Save As menu items.

    string saveFilename = "";
    private void saveAsMenuItem_Click(object sender, RoutedEventArgs e)
    {
      SaveFileDialog saveDialog = new SaveFileDialog();
      saveDialog.Filter = "XML file|*.xml";
      saveDialog.Title = "Save library";
      if (saveDialog.ShowDialog() == true)
      {
        saveFilename = saveDialog.FileName;
        saveMenuItem_Click(sender, e);
        Title = "Library - " + saveDialog.FileName;
      }
    }

    private void saveMenuItem_Click(object sender, RoutedEventArgs e)
    {
      if (saveFilename.Equals(""))
      {
        saveAsMenuItem_Click(sender, e);
      }
      else
      {
        XElement saveLibraryXml = XmlFromLibrary();
        saveLibraryXml.Save(saveFilename);
      }
    }

The SaveFileDialog (and OpenFileDialog) classes are in the old Microsoft.Win32 namespace, but they still seem to work well enough. In order to allow us to save changes to a currently open file, we have an auxiliary string called saveFilename. If this string has zero length, then we open the SaveFileDialog to get the user to select a filename. The dialog has a filter that displays only .xml files.

Once a file has been chosen, the saveMenuItem_Click() handler is called, and the method XmlFromLibrary() is called. We’ll consider this in a moment, but first we need to describe the XElement class.

In LINQ’s handling of XML, all XML tags are represented by XElement objects. There is no need for a separate, top-level document object in which to place the XElements; XElement itself can serve as the top level, and all lower levels.

Nested tags in the XML are represented simply as nested XElement objects. This gives the C# code a structure that is easy to understand for the human reader.

Now we can have a look at XmlFromLibrary():

    private XElement XmlFromLibrary()
    {
      ObservableCollection<Book> library = (ObservableCollection<Book>)((ObjectDataProvider)FindResource("LibraryGrid")).Data;
      XElement libraryElement =
        new XElement("LIBRARY",
          library.Select(book =>
            new XElement("BOOK",
              new XElement("AUTHOR", book.Author),
              new XElement("TITLE", book.Title),
              new XElement("PRICE", book.Price))));
      return libraryElement;
    }

After retrieving ‘library’ from the Windows resources, we create the XML representation of the library with a single C# statement. The top level object is libraryElement, which is given the tag LIBRARY. The second argument to its contructor is built using a LINQ Select() call on library. Remember that library consists of a list of Book objects, so we simply iterate through each Book in the list, and construct a new XElement for each Book. Within the Book’s XElement, we add 3 more XElements for the Author, Title and Price fields.

And that’s it. The code is very clean. Back in saveMenuItem_Click(), we simply call the Save() method from the XElement object to save the file to disk. The resulting file for the books shown in the picture above is:

<?xml version="1.0" encoding="utf-8"?>
<LIBRARY>
  <BOOK>
    <AUTHOR>Asimov, Isaac</AUTHOR>
    <TITLE>I, Robot</TITLE>
    <PRICE>3.50</PRICE>
  </BOOK>
  <BOOK>
    <AUTHOR>Niven, Larry</AUTHOR>
    <TITLE>Ringworld</TITLE>
    <PRICE>4.95</PRICE>
  </BOOK>
  <BOOK>
    <AUTHOR>Asimov, Isaac</AUTHOR>
    <TITLE>Foundation</TITLE>
    <PRICE>2.25</PRICE>
  </BOOK>
  <BOOK>
    <AUTHOR>Simak, Clifford D.</AUTHOR>
    <TITLE>Buckets of Diamonds</TITLE>
    <PRICE>5.00</PRICE>
  </BOOK>
</LIBRARY>

The Save() method produces the usual first line of an XML file, and then writes out the XML itself, all neatly indented.

To read the XML file back into the program, we need to construct the internal ObservableCollection from the XML. This is almost as easy as producing the XML in the first place. Here’s the code for the Open menu item, and the associated LibraryFromXml() method that reads the XML:

    private void openMenuItem_Click(object sender, RoutedEventArgs e)
    {
      OpenFileDialog openDialog = new OpenFileDialog();
      openDialog.DefaultExt = ".xml";
      openDialog.Filter = "XML documents (.xml)|*.xml";
      bool? result = openDialog.ShowDialog();
      if (result == true)
      {
        XElement libraryXml = XElement.Load(openDialog.FileName);
        Title = "Library - " + openDialog.FileName;
        LibraryFromXml(libraryXml);
        saveFilename = openDialog.FileName;
      }
    }

    private void LibraryFromXml(XElement libraryXml)
    {
      ObservableCollection<Book> library = (ObservableCollection<Book>)((ObjectDataProvider)FindResource("LibraryGrid")).Data;
      library.Clear();
      var bookElements = libraryXml.Elements("BOOK");
      foreach (XElement book in bookElements)
      {
        Book addBook = new Book(
          (string)book.Element("AUTHOR"),
          (string)book.Element("TITLE"),
          (decimal)book.Element("PRICE"));
        library.Add(addBook);
      }
    }

In the openMenuItem_Click() handler, we use the static XElement.Load() method to read the XML from the file into an XElement.

In LibraryFromXml() we again retrieve the library resource and clear it of existing data. Then we call the Elements() method on the XElement to retrieve a list of BOOK tags. This produces an IEnumerable list of XElements for the BOOK objects in the original XML. For each of these, we simply create a Book object by extracting the AUTHOR, TITLE and PRICE XElements for each BOOK, and then add this Book object to the library. The data binding takes care of the rest, so the DataGrid is automatically updated to display the list of books we read in.

There’s a lot more that can be done with LINQ and XML, but this little example should show you that for saving and reading basic XML, LINQ is easy to use.

Code for this post available here.