Override the ToString() Method

Override ToStringIf you hover over a collection of your objects in your debugger you probably see something that looks like Figure 2. By default the debugger calls the ToString() method to display this data. Instead of just taking this default, you should override the ToString() method in your class in order to display better data.


Figure 2: US States shown in the debugger

Override the ToString() method and use some property or properties in your class to return some meaningful data. For example, return the StateCode property plus the StateName property enclosed in parentheses from ToString() as shown below.

public partial class USState
{
  public string StateCode { get; set; }
  public string StateName { get; set; }
  public string Capital { get; set; }
  public override string ToString()
  {
    return StateCode + " (" + StateName + ")";
  }
}

After adding this override of the ToString() method when you run the application and look at the collection of states in the debugger you will now see real data as shown in Figure 3.


Figure 3: The US State objects now display more meaningful data in the debugger.

Another place the ToString() override comes in handy is if you forget to use a DisplayMemberPath in your WPF ListBox or ComboBox, or the DisplayTextField in WebForms. The ToString() method is called automatically when a class is bound to a list control and you forget to fill in the appropriate display property.

The DebuggerDisplay Attribute

An alternative to overriding the ToString() method is to add the [DebuggerDisplay] attribute to any one of your properties, or even at the class level to specify one or more properties to use in the debugging windows. The snippet below shows how you attach the DebuggerDisplay attribute to a property and specify the property name within quotes and braces.

public partial class Product
{
    public int ProductId { get; set; }
    [DebuggerDisplay("{ProductName}")]
    public string ProductName { get; set; }
}

When you create a collection of Product objects and display these within the Visual Studio debugger you will see the ProductName value display in any of the debugger windows. If you wish to display a couple of properties within any of the debugger windows, you attach the DebuggerAttribute to the class. You can then use literals and any property name within braces to display the data you want. In the code below you will see the ProductName value, a space, and the ProductId value contained within parentheses in the debugging windows.

[DebuggerDisplay("{ProductName} ({ProductId})")]
public partial class Product
{
}

An important point to remember is the DebuggerDisplay attribute only shows up in your debugging windows and will not have any affect at runtime. Overriding the ToString() method works in both debug and runtime mode. Many controls will call the ToString() method on an object if you forget to set the property name that displays your data.

You should be overriding the ToString method on all of your classes to help you with your debugging.


New Pluralsight Course on Unit Testing Released by Paul Sheriff

Unit TestingPluralsight is your go-to website for thousands of developer videos. Paul now has 13 courses available in the Pluralsight library. His latest is described below...

Basics of Unit Testing for C# Developers 

Every developer knows they should be creating Unit Tests to improve the quality of their applications. This course will walk you through creating unit tests using Visual Studio. You will see how easy it is to get started with creating unit tests. In addition, you will learn how to simplify the unit test process by creating data-driven tests. Finally, you will automate your unit tests by scheduling them to run via the command line utility VSTest.Console.
http://www.pluralsight.com/courses/basic-unit-testing-csharp-developers
Promo Video: http://bit.ly/2swbq56

Paul's Pluralsight Videos

In-Person Training / Mentoring

Would you like to experience our professional mentoring or training in person? Call Fairway Technologies today to discuss your training needs.

The Right Way to Use Reflection

Reflection Yes, we all know reflection is slow, but sometimes it is necessary to use it to satisfy a business requirement in our application. Just like anything, there is a right way and a wrong way to use reflection. Microsoft has made significant improvements in performance over the years for getting and setting properties. Make sure you are using the new ways of using reflection. Before I show you the new way to get and set properties, let's first learn about reflection and the old way of using it.

First off, let's say you have a Product class you have created that has a property named ProductName. If you wish to set the value of ProductName to a string, you write code like the following:

Product entity = new Product();
entity.ProductName = "A New Product";

Instead of hard-coding the name of the property to set, you might want to create a generic routine that you can pass a property name to and the value to set that property to. This can be accomplished using reflection as shown in the following code:

Product entity = new Product();
typeof(Product).InvokeMember("ProductName",
  BindingFlags.SetProperty,
    Type.DefaultBinder, entity,
     new Object[] { "A New Product" });

InvokeMember is a method of the System.Type class. The typeof() method returns an instance of the Type class which contains meta-data about the Product class. You pass 5 parameters to the InvokeMember method. The first parameter is the name of the property to set. The second parameter is the name of the property or method to invoke; in this case it is the Set property. The third parameter specifies to use the default binder. The fourth parameter is the variable with a reference to the instance of the class specified by the type (in this case the Product object). The last parameter is an object array of whatever you need to pass to the method or property you are invoking. For setting the ProductName property you only need a single object array of the string you are setting.

A Better Way to Set Property Values

While the InvokeMember method works for setting a property, it is quite slow. There is a more efficient way to set a property using reflection. There is a GetProperty method on the Type class you use to retrieve a PropertyInfo object. This PropertyInfo object has a SetValue method that you use to set the value on that property. Below is an example of calling the SetValue method.

Product entity = new Product();
 
typeof(Product).GetProperty("ProductName").
  SetValue(entity, "A New Product", null);
 
MessageBox.Show(entity.ProductName);

The above code is easier to understand than the InvokeMember method and is over 100% faster! That is a big difference, and you should take advantage of it when you need to use reflection to set properties.

Extend Classes using Extension Methods

Extension Methods Extension methods allow you to add your own custom method to an existing type. While this seems like a cool feature, there are a few reasons to use extension methods sparingly.

  • Adding too many extension methods to an existing type clutters the API.
  • If you name your extension method the same as a built-in method yours will never be called.
  • If you name your extension method the same as another extension method your method shadows the other extension method.

Because of the above points, you might consider just inheriting from the existing type and adding your own additional methods to this new class. But, with these disclaimers in place, let’s learn how you create extension methods because there are cases where using them is perfectly acceptable.

To create extension methods you define a static class with any name you like. Listing 1 shows a class named StringExtensions. This listing shows a couple of the available methods such as ReverseString and ToBoolean. All extension methods must also use the static keyword. The first parameter passed to an extension method is the same as the type you are extending and must be prefixed with the keyword “this”. Creating classes and methods using these rules informs the compiler to add these methods to the type specified in the first parameter.
public static class StringExtensions
{
  public static string Reverse(this string value)
  {
    char[] charArray = null;
    string ret = string.Empty;
    if (value != null)
    {
      charArray = value.ToCharArray();
      Array.Reverse(charArray);
      ret = new string(charArray);
    }
    return ret;
  }
  public static bool ToBoolean(this string value)
  {
    bool ret = false;
      
    switch (value.ToLower())
    {
      case "true":
      case "t":
      case "yes":
      case "y":
      case "1":
      case "-1":
        ret = true;
        break;
      case "false":
      case "f":
      case "no":
      case "n":
      case "0":
        ret = false;
        break;
      default:
        ret = false;
        break;
    }
    return ret;
  }
}
Listing 1: The StringExtensions class extends the string class with additional methods.

To use the methods shown in Listing 1, create an instance of type you are extending. After your new variable type a dot (.) and your extension methods show up in the IntelliSense as shown in Figure 1.


Figure 1: Using extension methods is the same as any other method on a type.

Summary

Extension methods are cool in that you can add methods to classes that you do not have the source to. However, be careful not to overuse them. You don't want the API to grow too large for a single class. You might consider using inheritance instead.

Generics Eliminate Duplicate Code

Generics Prior to .NET 2.0 when you needed a single method to work with different data types the only way to accomplish this was to pass an ‘object’ data type to that method. Working with the object data type introduces performance problems and bugs that can occur at runtime. The alternative is to create a new method for each data type that you wished to work with. This introduces a maintenance nightmare and leads to a larger API for programmers to learn. An example of using individual methods is shown in the code snippet that follows. Notice the calls to two different “ConvertTo” methods; ConvertToInt and ConvertToDateTime. The only difference between these two methods is the data types being passed in as parameters.


private void HardCodedNonGenericsSample()
{
  object value = "1";
  int i = ConvertToInt(value, default(int));
  value = "1/1/2014";
  DateTime dt = ConvertToDateTime(value, default(DateTime));
}

The ConvertToInt method shown in the following code snippet accepts two ‘object’ parameters and returns an ‘int’ data type.

public int ConvertToInt(object value, object defaultValue)
{
  if (value == null || value.Equals(DBNull.Value))
    return Convert.ToInt32(defaultValue);
  else
    return Convert.ToInt32(value);
}
Now look at the ConvertToDateTime method shown below. It is almost the exact same code except the return value is different and the use of the Convert.ToDateTime method instead of the Convert.ToInt32 method.
public DateTime ConvertToDateTime(object value, object defaultValue)
{
  if (value == null || value.Equals(DBNull.Value))
    return Convert.ToDateTime(defaultValue);
  else
    return Convert.ToDateTime(value);
}

Create One Generic Method

The two methods shown above can be rewritten in one method by using generics. To convert the above two methods into one you simply look at the data types in the two methods that are different. You substitute these differences with a “T” which stands for type parameter. The result is shown in the following code snippet:

public T ConvertTo<T>(object value, object defaultValue)
{
  if (value == null || value.Equals(DBNull.Value))
    return (T)Convert.ChangeType(defaultValue, typeof(T));
  else
    return (T)Convert.ChangeType(value, typeof(T));
}

The code “public T” means you have a public method that passes back the type specified in the <T> that comes after the method name. For the return type you cast either the ‘defaultValue’ or the ‘value’ to the type that was passed in.
To use this new ConvertTo method you pass in the data type you are converting into with a less than sign and a greater than sign as shown in the following code snippet:

private void HardCodedGenericsSample()
{
  object value = "1";
  int i = ConvertTo<int>(value, default(int));
  value = "1/1/2014";
  DateTime dt = ConvertTo<DateTime>(value, default(DateTime));
}

Generic Lists

Prior to .NET 2.0 you were required to create your own collection classes to provide type-safety. Type safety means you create a class that only allows you to pass in one type of object. For example, you may have a collection of string, int, or Product objects. You cannot pass an int to a string collection or a Product object to an int collection. To create a type-safe collection you inherit from the CollectionBase class and override many properties and methods. Listing 2 shows some of the code you are required to write for each unique collection class you wish to create. As you can see, this is quite a bit of code.

public class Int16Collection : CollectionBase
{
  public Int16 this[int index]
  {
    get
    {
      return ((Int16)List[index]);
    }
    set
    {
      List[index] = value;
    }
  }
  public int Add(Int16 value)
  {
    return (List.Add(value));
  }
  public int IndexOf(Int16 value)
  {
    return (List.IndexOf(value));
  }
  public void Insert(int index, Int16 value)
  {
    List.Insert(index, value);
  }
  public void Remove(Int16 value)
  {
    List.Remove(value);
  }
  public bool Contains(Int16 value)
  {
    return (List.Contains(value));
  }
  // Additional methods...
}
Listing 2: An example of using the old CollectionBase class.

Instead of writing all the code shown in Listing 2, you use one of the Generic collection classes instead. For example, you can replace the code in Listing 2 with just the following three lines of code!

public class IntCollection : List<int>
{
}

The class IntCollection class created in the previous code snippet is type-safe and will only accept an int data type. You cannot add a string or a decimal type to this collection. You get all of the same features you get with CollectionBase such as the ability to add, remove, insert and check to see if a value is contained within the collection. But you do not have to write all of the code for it.

The generic List<T> class is just one example of the many list classes available to you in the System.Collections.Generic namespace. Other examples are Dictionary<TKey, TValue> which allows you to store key/value pairs generically. You also have stacks, queues and linked lists implemented using generics. All of these save a ton of code and a ton of time.

Summary

Generics have been a great addition to .NET for many years now. Take advantage of these great constructs to cut down the amount of code you have to write.


String Handling Tips

String Handling Tips When working with strings, you should take advantage of certain classes and methods to avoid performance and memory problems. A key item to remember about .NET string is that they are immutable. Immutable means that strings are read-only and the value cannot be changed after it is created. If you add more data to the original string, a new instance of a string class is created to hold the new string and the old memory is marked for garbage collection. Thus, if you are doing a lot of string manipulation, you can create performance and memory issues in your application.

The StringBuilder Class for Concatenating

One way to avoid these issues is to use the StringBuilder class. The StringBuilder class is mutable so manipulations on strings are much quicker. You may pre-allocate space when creating an instance of the StringBuilder class. If you know you will be concatenating a lot of strings together pre-allocating space allows for growth without having to move memory blocks around. The methods Append, AppendLine and AppendFormat are what you will use to append new data into the StringBuilder object as shown below.

StringBuilder sb = new StringBuilder(1024);
sb.Append("Adding a new String without a line break.");
sb.AppendLine("Adding onto the previous line and add a line break");
sb.AppendFormat("Hello {0}", "Tom"); tbResult.Text = sb.ToString();

Other String Class Methods

A couple of other very useful techniques for working with strings are methods of the string class. The IsNullOrEmpty method helps you check to see if a string is a null value or an empty string. The use of this method is much better than using an "if" statement to check both. For example instead of 

1.	string value = null;
2. Debug.WriteLine(string.IsNullOrEmpty(value));
3.
4. value = "";
5. Debug.WriteLine(string.IsNullOrEmpty(value));
6.
7. value = " ";
8. Debug.WriteLine(string.IsNullOrEmpty(value));
9.
10. value = "Some Text";
11. Debug.WriteLine(string.IsNullOrEmpty(value));

The results of running the above code is "True", "True", "False" and "False". Notice that an empty space on line 7 is not an empty string. If you want to check for all white space within a string use the IsNullOrWhiteSpace as shown in the code snippet below:

string value = null;
Debug.WriteLine(string.IsNullOrWhiteSpace(value));
value = "";
Debug.WriteLine(string.IsNullOrWhiteSpace(value));
value = " ";
Debug.WriteLine(string.IsNullOrWhiteSpace(value));
value = "    ";
Debug.WriteLine(string.IsNullOrWhiteSpace(value));

The results of running the above code is "True", "True", "True" and "True". Regardless of whether you have an empty string, a string with 1 space, or a string with several spaces the IsNullOrWhiteSpace method is perfect for checking user input. Some users may try to enter a lot of spaces to get around a required field. Using this method can help you ensure that spaces will not get by your requirement for a field that has actual data in it.

No matter how long you have been working with the .NET framework, you can always find something new to learn about. I hope these couple of tricks will help you in your programming.

An Alternative to HTML Tables

I have long had a problem with using HTML tables to display data to the user. I have an even bigger problem with editing on a table, but that is a different discussion. An HTML table is easy to implement for a developer, and this is normally why developers use them. However, a table is not always the best method for conveying data to a user, especially when that data is most likely viewed on a mobile device. Of course, there are always exceptions to this rule, but these should be "the exception" and not the rule. There are many reasons why a table is not suitable for user consumption.

  • A table presents too much data on the screen so the user's eye has too much to try to concentrate on.
  • A user will get much more tired at the end of the day using a table as opposed to other display types.
  • The user cannot distinguish between the data in each column since each column is very uniform and nothing stands out.

The above are just some of the reasons why a table might not be the appropriate choice for displaying a list of data to the user. Look at Figures 1 and 3 for an example of a normal HTML table displayed in both a normal browser and on a mobile device. Then look at Figures 2 and 4 which should the alternative display of the same data on a desktop browser and a mobile device. As you can see the alternative design displays the data in a much easier-to-read format.

Using a HTML Table

A list of product data in a normal HTML table renders fine on a desktop browser, as illustrated in Figure 1. However, if you display that same product data on a mobile browser, you might only see the left most columns as illustrated in Figure 2. On some mobile browsers, they may render the table so small that it is hard to read. Either way, the user is forced to interact with their phone to view the data. They will either have to scroll left to right, or maybe pinch or spread with their fingers.


Figure 1: An HTML table rendered on a desktop browser.


Figure 2: An HTML table rendered on a mobile browser.

Using a Bootstrap Panel

Instead of using an HTML table, you might display a list of Bootstrap panel controls that contain your product data. In the sample shown in Figure 3 you see the same data, but the most important data, the product name, is displayed in the panel header area. The other information about the product is displayed within the body of the panel. The actions you can take are displayed within the panel footer area. As you can see this list of data looks just as good on a normal desktop browser (Figure 3) as on a mobile browser (Figure 4).


Figure 3: An alternative approach to a list of data rendered on a desktop browser.


Figure 4: An alternative approach to a list of data rendered on a mobile browser.

Create Mock Data Classes

Instead of messing with a database, create three simple classes to build a collection of Product objects that can be rendered on an MVC page. Figure 5 illustrates the properties and methods of each of the 3 classes. To view the code for these classes, see the instructions at the end of this blog post on how to download the sample.


Figure 5: A set of 3 product classes help us load mock product data for this sample

The MVC Controller

You need a MVC controller to load the data and feed that data to the CSHTML pages used to render our two pages of product data. Below is the code from the MVC controller. The TableSample and AlternateTableSample methods create an instance of the TrainingProductViewModel class and call the LoadProducts method to build the Products property in the view model. It is the collection property that is used to display the list of data in both pages.

public class HomeController : Controller
{
  public ActionResult Index() {
    return View();
  }
  public ActionResult TableSample() {
    TrainingProductViewModel vm = new TrainingProductViewModel();
    vm.LoadProducts();
    return View(vm);
  }
  public ActionResult AlternateTableSample() {
    TrainingProductViewModel vm = new TrainingProductViewModel();
    vm.LoadProducts();
    return View(vm);
  }
}

Create the HTML Table

The TableSample page is the one that renders the standard HTML table. Below is the code from the TableSample.cshtml page.

@model AlternativeTable.TrainingProductViewModel
@{
  ViewBag.Title = "Table Sample 1";
}
<h2>Table Sample 1</h2>
@using (Html.BeginForm()) {
  <div class="table-responsive">
    <table class="table table-bordered
                  table-condensed table-striped">
      <thead>
        <tr>
          <th>Product Name</th>
          <th>Introduction Date</th>
          <th class="text-right">Price</th>
          <th>URL</th>
          <th>Delete</th>
        </tr>
      </thead>
      <tbody>
        @foreach (TrainingProduct item in Model.Products) {
          <tr>
            <td>
              <a href="#"
                 title="Edit Product">
                @item.ProductName
              </a>
            </td>
            <td>@item.IntroductionDate.ToShortDateString()</td>
            <td class="text-right">@item.Price.ToString("c")</td>
            <td>@item.Url</td>
            <td>
              <a href="#"
                 title="Delete Product"
                 class="btn btn-sm btn-default">
                <i class="glyphicon glyphicon-trash"></i>
              </a>
            </td>
          </tr>
        }
      </tbody>
    </table>
  </div>
}

As you can see from the above code, there is nothing out of the ordinary for this table. You use the Bootstrap table classes to help with styling the table. You loop through the collection of product data in the Products property of the TrainingProductViewModel class. Each time through the loop, you display the appropriate data from the Product class in each <td> of the table.

Create the Alternative Design

The AlternateTableSample page uses the appropriate Bootstrap panel CSS classes to create the alternative design shown in Figures 2 and 4. Below is the code in the AlternateTableSample.cshtml page.

@model AlternativeTable.TrainingProductViewModel
@{
  ViewBag.Title = "Alt. Table Sample 1";
}
<h2>Alt. Table Sample 1</h2>
@foreach (TrainingProduct item in Model.Products) {
  <div class="panel panel-primary">
    <div class="panel-heading">
      <h1 class="panel-title">@item.ProductName</h1>
    </div>
    <div class="panel-body">
      <div class="row">
        <div class="col-xs-4 hidden-sm hidden-md hidden-lg">
          Intro Date
        </div>
        <div class="col-xs-4 col-md-3 hidden-xs">
          Introduction Date
        </div>
        <div class="col-xs-8 col-md-9">
          @item.IntroductionDate.ToShortDateString()
        </div>
      </div>
      <div class="row">
        <div class="col-xs-4 col-md-3">
          Price
        </div>
        <div class="col-xs-8 col-md-9">
          @item.Price.ToString("c")
        </div>
      </div>
      <div class="row">
        <div class="col-xs-4 col-md-3">
          URL
        </div>
        <div class="col-xs-8 col-md-9">
          @item.Url
        </div>
      </div>
    </div>
    <div class="panel-footer">
      <div class="row">
        <div class="col-xs-12">
          <a href="#"
             title="Edit Product"
             class="btn btn-sm btn-default">
            <i class="glyphicon glyphicon-edit"></i>
          </a>
          <a href="#"
             title="Delete Product"
             class="btn btn-sm btn-default">
            <i class="glyphicon glyphicon-trash"></i>
          </a>
        </div>
      </div>
    </div>
  </div>
}

Let's look at each section of the above code to see how it was put together. The first thing you see is the loop through the Model.Products collection. Within this loop is where you build a complete Bootstrap panel. In the heading area of the panel is where you place the ProductName property. Within the panel body is where you create a row and two columns for each of the other properties you wish to display from the Product object.

Notice that I am changing the column widths I use depending on the size of the browser. For anything that is a medium resolution and above, (according to Bootstrap) I am using a col-md-3 for the first column and col-md-9 for the second column. However as soon as a mobile device is detected, use the size of col-xs-4. If you look at the Introduction Date field you also notice that the words used are changed also depending on the size of the browser. This is one of the great things about using Bootstrap, the ability to hide and display things using simple CSS classes.

The last difference in this code compared to the normal HTML table is I use two glyphs for the actions that the user can take. It can be sometimes hard to click on a hyperlink with your finger on a mobile device. They can even be hard to see sometimes on a mobile device. I find using large buttons with a graphic gives the user a nice big target to hit with their finger.

Summary

In this blog post, you were presented with a method to present data to the user that is different from a traditional HTML table. While you may not like the exact user interface presented here, hopefully this article will spur you to question your user interfaces a little more and come up with some alternate methods of displaying lists of data.

Sample Code

You can download the complete sample code at my website. http://www.pdsa.com/downloads. Choose "PDSA Blog", then "An Alternative to HTML Tables" from the drop-down.


Keep Your Software Up-To-Date

Yes, it is always a struggle to keep your software up-to-date, but it is vital that you do so. Microsoft and Apple upgrade their operating systems every couple of years. Sometimes, when they do this, they break compatibility with their older operating system (OS). While this might be fine for most software, sometimes it does cause older software running on the new OS to break. If you have older software such as software written using Visual Basic 6 or earlier, FoxPro, PowerBuilder, and others, this means you are at risk of your software no longer working.

So, you might be thinking that you can just require your customers to run on the older operating systems. This might work for a couple of years, but at some point, your customers are going to want to, or need to, upgrade to the new OS. In fact, they may have to as Microsoft and Apple no longer support the older OS. There can be very serious consequences for not upgrading such as security risks. In today’s world with identity theft on the rise, people need to take every precaution to keep their computers safe. Staying current on the new OS versions is one way to stay safe.

You have a lot of time and money invested in your old software, and rewriting it can be an extensive undertaking. However, when you look at the alternative that your software no longer works, and you can no longer run your business, or your customers no longer purchase your software, how much is that worth? Could your business fail because of old software? This could be a real possibility.

So, the time to be looking at updating your software to new versions of .NET or Java is now, not when it stops working on a new OS release. By the time it stops working, you might not have enough time to rewrite before all your customers move on and you are now out of business.

Fairway Technologies can assist you with the migration of your old software to the most up-to-date languages and platforms. Call us today for a free consultation and let us help guide you on your path to new software that will last for years to come.

Use LINQ to XML Instead of a Database

When people think of having to store data for their applications, a database such as SQL Server immediately comes to mind. However, XML files are very handy for storing data without the overhead of a database. Using XML files to cache often-used, but seldom changed data such as US state codes, Country code, employee types and other validation tables can avoid network round-trips to a database, and potentially speed up your application. In addition, XML files are great for off-line applications where a user needs to add, edit and delete data when they can’t connect to a database.

To take advantage of XML within your application, you should use LINQ to XML. I am sure you have used LINQ to iterate over other types of collections. LINQ works great to iterate over XML, too. In this blog post you will use LINQ to XML to read state codes from an XML file and display those values on a web page.

The US State Codes XML File

An XML data file called USStates.xml is in the \Xml folder of the MVC project that you can download (see the instructions at the end of this post). This XML file contains several elements of US state code data. Each row has 3 elements as shown below

<USStates>

  <USState>
    <StateCode>AK</StateCode>
    <StateName>Alaska</StateName>
    <Capital>Juneau</Capital>
  </USState>
</USStates>

The USState Class

Just as you create an Entity class to map each column in a table to a property in a class, you should do the same for an XML file too. In this case you will create a USState class with properties for each of the elements within the parent element.

public class USState
{
  public string StateCode { get; set; }
  public string StateName { get; set; }
  public string Capital { get; set; }
}

The USStateManager Class

To read the US state codes from the XML file, make sure you have a reference to the System.Xml.Linq.dll in your project. Create a class called USStateManager. This manager class is going to have a method named GetStateCodes to which you pass in the full path and file name where the USStates.xml file is located in your MVC project. The full class listing is shown below. Take a look at the code, then we will discuss each piece.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace LinqToXmlSample
{
  public class USStateManager
  {
    public List<USState> GetStateCodes(string fileName) {
      // Load the XML file
      XElement xelem = XElement.Load(fileName);
      // Fill a list of USState objects
      var coll = from elem in xelem.Descendants("USState")
        select new USState
        {
          StateCode = GetValue<string>(elem.Element("StateCode"),
                                       ""),
          StateName = GetValue<string>(elem.Element("StateName"),
                                       ""),
          Capital = GetValue<string>(elem.Element("Capital"), "")
        };
      return coll.ToList();
    }
    private T GetValue<T>(XElement elem, T defaultValue) {
      if (elem == null || string.IsNullOrEmpty(elem.Value)) {
        return defaultValue;
      }
      else {
        return (T)Convert.ChangeType(elem.Value, typeof(T)); ;
      }
    }
  }
}

At the top of this file, you need a few using statements to support the various classes you use for reading in the XML and creating a list of USState objects. The GetStateCodes method accepts a fully qualified path and file name to the US state codes xml file. Using the XElement class, pass the file name to the Load() method. This method loads the XML file and returns an XElement object.

Once the XML file has been loaded, you write a LINQ query to iterate over the “USState” Descendants in the XML file. The “select” portion of the LINQ query creates a new USState object for each row in the XML file. You retrieve each element by passing each element name to the Element() method. This method returns an XElement object. This object has Value property from which you can retrieve the value, or a null value if the element does not exist.

Because you do not want to have a null value returned, a GetValue() method is written to accept an XElement object and a default value. This generic method checks to make sure that the XElement is not null, or that the value in the XElement object is not null or an empty string. If it is, then the default value you pass in is returned. If there is a value in the element, then that value is converted into the specified data type.

Calling the GetStateCodes Method

Now that you have written the code to retrieve the state codes and have them returned in a list of USState objects, let’s now call this method from a controller and display the state codes in a unordered list on an HTML page. Create a MVC controller named USStateController. Write the following code to create an instance of the USStateManager class, get the path and file name to the USStates.xml file, and call the GetStateCodes method.

public class USStateController : Controller
{
  public ActionResult Index() {
    USStateManager mgr = new USStateManager();
    string fileName = Server.MapPath("/Xml") + @"\USStates.xml";
    return View(mgr.GetStateCodes(fileName));
  }
}

Once you call the GetStateCodes method, the list of USState objects is passed directly to the CSHTML page via the View() method. The CSHTML page looks like the following. This page loops through each state code in the Model and builds a simple unordered list.

@model List<USState>
@{
  ViewBag.Title = "US State Codes";
}
<div class="row">
  <div class="col-md-12">
    <ul>
      @foreach (USState state in Model) {
        <li>
          @state.StateName (@state.StateCode)
        </li>
      }
    </ul>
  </div>
</div>

Summary

XML files can be a great alternative to storing data in a SQL Server table. LINQ to XML is a great way to retrieve data from those XML files, and if the files are stored on the web server, they can increase performance because you don’t have to go across the network to a database server. I have used LINQ to XML to work with XML files up to 10,000 rows of data and have seen a less than a second response times. I am sure you will find a lot of uses for XML in your applications.

Sample Code

You can download the complete sample code at my website. http://www.pdsa.com/downloads. Choose "PDSA Blog", then "Use LINQ to XML Instead of a Database" from the drop-down.


8 Questions to Ask to Determine if you should be in the Cloud

Everyone wonders if they should be moving to the cloud. Here are 8 starter questions you should ask yourself. Are you...


  1. Spending too much time on your IT infrastructure?
  2. Anticipating future growth?
  3. Needing to react quickly to change?
  4. Tired of hassling with Microsoft Exchange?
  5. Wanting to run your software as a service?
  6. Constantly adding more hardware to run your company
  7. Worried that your servers may not be backed up properly?
  8. Concerned about disaster recovery?

If you answered "Yes" to even one of these questions, a cloud solution may be just what you need. Companies are successfully using the cloud to scale their applications up and down without purchasing more equipment for the organization. Moving your applications into the cloud offers multiple benefits including:

  • Better security
  • Less manpower needed to manage software updates
  • More flexibility in application management
  • Disaster recovery is easier

If any of these keep you up at night, you should consider moving into the cloud. Fairway Technologies can help you migrate your infrastructure and your software to the cloud. Read more in our special report entitled Why Move to the Cloud?