When you think ASP, think...
Recent Articles xml
All Articles
ASP.NET Articles
Related Web Technologies
User Tips!
Coding Tips
spgif spgif

Book Reviews
Sample Chapters
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Stump the SQL Guru!
Web Hosts
Author an Article
spgif spgif

ASP ASP.NET ASP FAQs Feedback topnav-right
Print this Page!
Published: Wednesday, February 4, 2009

Creating a "What I'm Reading" Widget

By Scott Mitchell


A number of personal websites and blogs have a "What I'm Reading" section, where the site owner lists books he's currently reading. Typically these widgets include a cover image of the book, the title and author, and a link the web visitor can click to buy the book or learn more about it. I recently needed to create a similar sort of widget for a website I was working on. This website did not require anything overly fancy, it just needed a simple administrative interface where the website administrator could enter book information and a User Control that he could drop on a web page that would display his current reading queue.

The solution I created uses an XML file to store information about the books displayed in the "What I'm Reading" User Control. The User Control uses a ListView and an XmlDataSource to display the books in the XML file in a series of <div> elements. And the administration page use a ListView control and the LINQ to XML library to provide a web-based interface for adding, updating, and deleting data from this XML file.

This article looks at how I built the User Control and administration interface. The complete source code (in C#) and a demo application is available for download. Read on to learn more!

- continued -

The What I'm Reading User Control displays the books in the ReadingList.xml file.

An Overview of the "What I'm Reading" User Control and Administrative Interface

The first design decision I faced when creating this widget was how to store the book information. I usually prefer storing data in a database, but decided against it in this case for a few reasons. First, the person I created this widget for wanted to be able to re-use this widget on other ASP.NET sites by simply uploading a few files to his web host provider. He did not want to have to worry about adding database tables, configuring database connection strings, and the like. He also wanted the ability to be able to have several different web properties use the same book data without having to maintain the information in all sites.

Given these requirements I decided to store the data in an XML file. By using an XML file the person using this widget doesn't need to bother creating a database table, and this widget can be used on sites that don't use a database. But it was the second requirement - the ability to have multiple websites all pull from the same data source - that cemented my decision to use XML. A single XML file can be maintained on one site (say, www.mainsite.com) and the other sites, which could be located on different web servers or even at different web host providers, can display this data by pulling the information from www.mainsite.com/ReadingList.xml (or whatever you name the XML file). The one potential downside of choosing XML in a hosted scenario is that if the XML file is going to be modified from an ASP.NET page, as it is in this case, then the user account that the ASP.NET engine operates under must be given modify permissions to the XML file. The good news is that most every web host provider offers a tool in their Control Panel that lets you adjust file system permissions.

In the past, XML was not always the easiest data store to work with. However, today it is incredibly easy to display, edit, update, and delete XML data. ASP.NET's XmlDataSource control can be used to display data in a data Web control without having to write a line of code. And the LINQ to XML framework that was introduced in ASP.NET version 3.5 allows for XML data to be queried, edited, and deleting a matter of a few lines of code. This was another reason why I decided to store the data in an XML file.

The entire "What I'm Reading" widget is composed of an XML file, a User Control, and an administrative web page, all of which are available for download at the end of this article (along with a demo application that shows these features in action). In the demo application the XML file is located named ReadingList.xml and is located in the App_Data folder. (Note: ASP.NET prohibits HTTP access to the App_Data folder, meaning that any files in this directory are not accessible from an HTTP request. Consequently, if you plan on sharing a single XML file across multiple websites, as I mentioned earlier, then you will have to move this XML file out of the App_Data folder.)

The ReadingList.xml has the following structure:

      <title>Book title</title>
      <author>Book author(s)</author>
      <link>URL to page where the visitor can buy or learn more about the book</link>
      <imageUrl>The URL of the book's image cover</imageUrl>

<books> is the root element; it contains a <book> child element for each book that will appear in the "What I'm Reading" User Control. Each <book> element has four children elements that supply the values for the four book attributes noted earlier: the book's title, the author(s), a URL for more information about the book, and a URL for the book's cover image. All of these fields are required.

The User Control, WhatImReading.ascx, essentially transforms the XML in the ReadingList.xml XML file into HTML. Specifically, it generates a series of <div> elements with anchor and image elements that show the book cover image, the title, and the author, linking the image and title to the URL specified in the book's <link> element. The screen shot on the right shows the User Control's output when there are three <book> elements in the XML file and produces the following (abbreviated) markup:

<div class="skm_BookReviewContainer">
   <div class="skm_BookReview">
      <a href="link"><img src="imageUrl" style="border-width:0px;" /></a>

      <div class="skm_BookReviewByline">
         <a href="link">title</a>
         by author

   <div class="skm_BookReview">


The final piece of the "What I'm Reading" widget is an administrative interface, ~/Admin/EditReadingList.aspx. This page uses a ListView control and some LINQ to XML code in the code-behind class to provide an interface for adding new books to the XML file and for editing and deleting existing books. The user interface for this page is quite intuitive and doesn't need a lot of explanation.

The What I'm Reading web-based administration page.

Displaying the Books in the User Control

The WhatImReading.ascx User Control displays the books in the XML file using an XmlDataSource control and a ListView. The XmlDataSource control returns the contents of a local or remote XML file returns a set of nodes in the XML document; you can use an optional XPath expression to narrow down the nodes returned. While not shown in the demo application available for download, you could configure the XmlDataSource to reference a remote XML file, such as www.mainsite.com/ReadingList.xml. The XmlDataSource control's DataFile property indicates the location of the XML file, and it can point to a local file, like "~/ReadingList.xml", or a remote file, like "http://www.mainsite.com/ReadingList.xml".

The XmlDataSource in the User Control pulls in the XML content from the ReadingList.xml file and returns the set of book nodes by specifying the XPath expression /books/book. This data source control is bound to a ListView control, which renders the cover image as a hyperlink along with the title and author(s) information.

<asp:ListView ID="myBookList" runat="server" DataSourceID="BooksDataSource">
      <div class="skm_BookReviewContainer">
         <asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
      <div class="skm_BookReview">
         <asp:HyperLink runat="server" ID="lnk1" NavigateUrl='<%# XPath("link") %>' ImageUrl='<%# XPath("imageUrl") %>' />

         <div class="skm_BookReviewByline">
            <asp:HyperLink runat="server" ID="lnk2" NavigateUrl='<%# XPath("link") %>' Text='<%# XPath("title") %>' />
            by <%# XPath("author") %>

<asp:XmlDataSource ID="BooksDataSource" runat="server"
   DataFile="~/App_Data/ReadingList.xml" XPath="/books/book">

The XmlDataSource control returns one "record" for each <book> element in the XML document. Each <book> element's content can be accessed via data binding syntax, <%# XPath("expression") %>. For example, to retrieve the value of the <book> element's <title> element the syntax <%# XPath("title") %> is used.

For more information on using the ListView control refer to Using ASP.NET 3.5's ListView and DataPager Controls. For a deeper look at working with the XmlDataSource control, see Retrieving XML Data with XmlDataSource Control.

Managing the XML File Contents Through a Web-Based Interface

The XmlDataSource control is a handy tool for displaying XML data, but it does not offer built-in functionality for editing and deleting content from the XML document (like the SqlDataSource does). The good news is that it is quite easy to modify XML data using the LINQ to XML library, which was introduced in the .NET Framework version 3.5. A previous article on 4Guys by Miroslav Kadera, Working with XML Data Using LINQ, a TreeView, and a ListView, showed how with a few dozen lines of code you could build a page that provided a web-based interface for adding, updating, and deleting nodes from an XML document. I took Miroslav's code and example, tweaked it a bit, and used it to craft the administrative interface for this widget.

The ~/Admin/EditReadingList.aspx page contains a ListView that defines an ItemTemplate, EditItemTemplate, and InsertItemTemplate. The ItemTemplate displays a read-only interface that lists the title, author, link, and image URL for each <book> element in the XML file. The EditItemTemplate and InsertItemTemplate replicate this interface, but replace the read-only text with TextBoxes from which the user can specify the value for these book fields. The InsertItemTemplate is shown at the top of the ListView control, while the EditItemTemplate is shown only when a book's "Edit" button is clicked.

The ListView is populated via a few lines of LINQ to XML code. Likewise, LINQ to XML code is used to add a new node to the document, edit an existing node, or delete a node. I'm not going to go into an in-depth look at the markup and code in the administration page, as the nuts and bolts of the code and markup is already covered Working with XML Data Using LINQ, a TreeView, and a ListView. For a detailed look at how the administration page works and to see how LINQ to XML can be used to help build such a versatile web page, be sure to check out Miroslav's article.

Be Sure to Secure the Administration Page!
While the administrative page is in a folder named ~/Admin, there are no authorization rules applied to this page. Consequently, the administration page is accessible to anyone who visits the site. If you are going to use the "What I'm Reading" widget on a live website be sure to place the administration in a folder that is sufficiently locked down. For more information on website security check out my Security Tutorials.


This article showcased a "What I'm Reading" widget that you are welcome to add to your website or extend in any way you like. The widget pulls its data from an XML file and includes a User Control that displays the list of books in the XML file as well as an administrative web page that offers a web-based interface for managing the XML data. Thanks to ASP.NET's XmlDataSource control and the LINQ to XML library, displaying and modifying XML data is a walk in the park.

Happy Programming!

  • By Scott Mitchell


  • Download the "What I'm Reading" Code (includes source code and demo app)
  • Further Reading

  • Working with XML Data Using LINQ, a TreeView, and a ListView
  • Retrieving XML Data with XmlDataSource Control
  • XPath Tutorial
  • Using ASP.NET 3.5's ListView and DataPager Controls
  • LINQ to XML Information

  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article