Object Serialization and Deserialzation in c#

Previously I have written about how to serialize an object to XML. This post is an improved version of that post with better code and the addition of a deserialize example.
Required Namespace to be imported for serialization is System.Xml.Serialization.

This example is also available as a gist

public class Person
{
    public string Name {get; set;}
    public int Age {get;set;}
    public Address Address{get;set;}
}

public class Address
{
    public string Address1 {get;set;}
    public string Town {get;set;}
    public string PostCode{get;set;}
}

void Main()
{
    var p = new Person{
        Name = "John Jones",
        Age = 40,
        Address = new Address{
        Address1= "Daisy Meadow",
        Town="Chorville",
        PostCode = "CH1 1HC"
    }
};
	
XmlSerializer xmlSerializer = new XmlSerializer(p.GetType());
	
var xmlText = string.Empty;
using (TextWriter textWriter = new StringWriter()){
    xmlSerializer.Serialize(textWriter, p);
    xmlText = textWriter.ToString();
}

XmlReaderSettings settings = new XmlReaderSettings();
using(StringReader textReader = new StringReader(xmlText)) {
    using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {
         ((Person)xmlSerializer.Deserialize(xmlReader)).Dump();
        }
    }
}

Handling Complex Fake or Test Data When Unit Testing-Builder Pattern

The data supporting the unit tests you are creating may have classes that contain other classes as properties. Here we have a Person class that contains an Address class

public class Person{
	public string FirstName {get;set;} 
	public string LastName {get;set;}
	public Address Address{get;set;}
}

public class Address{
	public string Address1{get;set;}
	public string PostCode{get;set;}
	public string Country{get;set;}
}

There are a number of possible scenarios to be unit tested, i.e. If the address is missing or invalid or missing person details. For each unit test the test objects will need to be created which could easily result in duplicate or just tedious typing. For example objects similar to the one below may need to be created with slightly different data for each test.

var person = new Person{
	FirstName="Joe",
	LastName="Bloggs",
	Address=new Address{
		Address1="1 The Grove",
		PostCode="PembroVille",
		Country="United Kingdom"	
	}
};

A real life scenario could involve more complex classes than this example resulting in more tedious duplication. One useful trick is to create a builder class to easily build objects that cater for different test scenarios. In this builder class you can configure the data for each different positive and negative test with the advantages of configure once, reusable code.
Below is a PersonBuilder class which aids in building a Person object with different data relevant to the tests being performed.

public class PersonBuilder
{
    private Person _person = new Person();

    public Person Build(){
        // Set standard default values for properties here if needed
        return _person;
    }

    public PersonBuilder WithValidDetails()
    {
        _person.FirstName="Joe";
        _person.LastName="Bloggs";
        return this;
    }

    public PersonBuilder WithValidAddress()
    {
        _person.Address=new Address{
            Address1="1 The Grove",
            PostCode="PembroVille",
            Country="United Kingdom"
        };
        return this;
    }
	
    public PersonBuilder WithInValidAddress()
    {
        _person.Address=null;
        return this;
    }
}

I can build an empty Person

	var person = new PersonBuilder().WithValidDetails().Build();

A Person with valid details and an valid address

var person = new PersonBuilder().WithValidDetails().WithValidAddress().Build();

This is a somewhat simplified example which would work easily well with complex classes.

Using EntityFramework 6 Part 2: Database Connections

This post is part of a mini series on using EntityFramework (EF). If you do not have EF installed go to Part 1: Introduction and Setup to see what (basic) steps we took to get EF installed.
In this part we are going to use Code-First methods to start model building, then eventually connecting to the database . This is not the only way and you do not have to do things in exactly the same order as I have but if you follow along you should have a working version at the end.

Database
Firstly, create a database at your preferred location. Once you have a database add the connection string to the web.config file. I added a database to the App_Data folder so this is what the connectionsString definition look like in my web.config file.

  <connectionStrings>
    <add name="DBConn" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\DB.mdf;Integrated Security=True"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

Next, add a class which inherits from DBContext. An instance of DBContext, LibraryDBContext in this example, is used to perform CRUD operations against a database. To read up on DBContext see these articles
http://www.entityframeworktutorial.net/EntityFramework4.3/dbcontext-vs-objectcontext.aspx

namespace WebApplication2.Models
{
    public class LibraryDBContext:DbContext
    {
        public LibraryDBContext() : base("DBConn")
        { }

        public DbSet<Book>Books{ get; set; }
    }
}

This gives sufficient Entity Framework code to enable our application to access a database.

The Model
Now we will start the model by creating a Book entity. Create a Book class in the Models folder of your application.

namespace WebApplication2.Models
{
    public class Book
    {
        public int BookId { get; set; }
        public string Author { get; set; }
        public string Title { get; set; }
    }
}

Following Code-First conventions, because we have defined an property called BookId (class name ‘Book’ plus ‘Id’) Entity Framework will nominate this property as an identity column when the database tables are generated. If we had a property simply named Id, Entity Framework would have nominated that as the identity and created an identity column called Id.

Displaying Book Info
Add a Controller to the application, I have called it BooksController. The Index action retrieves all the books from what will be the Books table.

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class BooksController : Controller
    {
          public ActionResult Index()
        {
            var books = new List<Book>();
            using (var db = new LibraryDBContext())
            {
                books = db.Books.ToList();
            }
            return View(books);
        }
    }
}

The last code related change is to create a View for the Index Action to display all the books.

@model IEnumerable<WebApplication2.Models.Book>
    @Html.ActionLink("Create New", "Create")
<table class="table">
<tr>
<th>
            @Html.DisplayNameFor(model => model.Author)</th>
<th>
            @Html.DisplayNameFor(model => model.Title)</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
            @Html.DisplayFor(modelItem => item.Author)</td>
<td>
            @Html.DisplayFor(modelItem => item.Title)</td>
<td>
            @Html.ActionLink("Edit", "Edit", new { id=item.BookId }) |
            @Html.ActionLink("Details", "Details", new { id=item.BookId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.BookId })</td>
</tr>
}</table>

Running the Application
The application should build at this point. Currently we have a database that contains no tables. If you run the application now The database/tables will only be created/modified on a read/write action. So run the application and navigate to your controller (e.g. \books). Because the Index action of the Books controller contains code that retrieves data via the inherited DBContext class, and because Entity Framework knows there are models with no corresponding database table, the tables will be created with columns types that match the model properties.

Simple ASP.Net Gridview Sorting and Paging Example

The simplest way to perform paging and sorting in an ASP.Net webforms application is to use the SQLDatasource control. If you do not use the suite of DataSource controls paging and sorting can manually be achieved without too much extra work.

The page contains a GridView control that has paging and sorting enabled by setting AllowPaging and AllowSorting attributes to true. Height and width are optional.

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" Height="292px" 
OnDataBound="GridView1_DataBound" OnPageIndexChanging="GridView1_PageIndexChanging" OnSorting="GridView1_Sorting" 
Width="600px"></asp:GridView>

As I am not using any data access methods, I have created a private method to generate and return a DataTable of data.

private DataTable GetTableData()
{
	DataTable dt = new DataTable();
	dt.Columns.Add("ProductId", typeof(int));
	dt.Columns.Add("Name", typeof(string));
	dt.Columns.Add("ProductNumber", typeof(string));
	dt.Columns.Add("Quantity", typeof(int));
	dt.Columns.Add("UnitPrice", typeof(decimal));

	Random rnd = new Random();
	for (var i = 1; i <= 100; i++)
	{
		var qty = rnd.Next(1, 100);
		DataRow dr = dt.NewRow();
		dr["ProductId"] = i;
		dr["Name"] = $"Product{i}";
		dr["ProductNumber"] = $"A-{qty}";
		dr["Quantity"] = qty;
		dr["UnitPrice"] = i;
		dt.Rows.Add(dr);
	}
	return dt;
}

The webform has two properties that are used as accessors to values stored in viewstate, the name of the sort column and the sort direction.

public string SortColumn
{
	get {return Convert.ToString(ViewState["SortColumn"]);}
	set {ViewState["SortColumn"] = value;}
}

public string SortDirection
{
	get { return Convert.ToString(ViewState["SortDirection"]); }
	set { ViewState["SortDirection"] = value; }
}

In the page load method, if the page load was not from a postback the default sort direction and sort column is set and the BindGrid method is called.

protected void Page_Load(object sender, EventArgs e)
{
	if (!Page.IsPostBack)
	{
		SortDirection = "ASC";
		SortColumn = "ProductId";
		BindGrid();
	}
}

The Bind Grid method calls the GetTableData method to generate the data and the data is bound to the grid.

private void BindGrid()
{
	var dt = GetTableData();
	if (dt != null)
	{
		//Sort the data.
		dt.DefaultView.Sort = SortColumn + " " + SortDirection;
		GridView1.DataSource = dt;
		GridView1.DataBind();
	}
}

The PageIndexChanging event is raised when one of the pager options is clicked, but before the GridView handles the paging operation. Notice the BindGrid method is called causing the grid to be rebound to the data.

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
	GridView1.PageIndex = e.NewPageIndex;
	BindGrid();
}

The Sorting event is raised when the column header link is clicked, but before the GridView control handles the sort operation. Here the sort expression, in this case the data column to sort by and the sort order are set. The data is then rebound by calling the BindGrid method.

		
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
	SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
	SortColumn = e.SortExpression ;
	BindGrid();
}

The DataBound event fires when all the databinding for the GridView is finished. All we do here is find the index of the GridView column that matches the sort expression and add an image to the column header to indicate the current sort direction.

protected void GridView1_DataBound(object sender, EventArgs e)
{
	int columnIndex = 0;
	foreach (DataControlFieldHeaderCell headerCell in GridView1.HeaderRow.Cells)
	{
		if (headerCell.ContainingField.SortExpression == SortColumn)
		{
			columnIndex = GridView1.HeaderRow.Cells.GetCellIndex(headerCell);
			break;
		}
	}

	Image sortImage = new Image();
	sortImage.ImageUrl = string.Format("images/sort-{0}ending.png", SortDirection);
	GridView1.HeaderRow.Cells[columnIndex].Controls.Add(sortImage);
}

That is pretty much it.

Using HtmlHelpers to generate HTML elements (Part 1)

When working in a Microsoft MVC application, creating forms containing form elements is made easier due to the number of available HtmlHelper methods for a TextBox, DropDownList, TextArea etc. Although HtmlHelpers are not only available for form controls, there are helpers for links, view rendering, validation and more built in to the MVC libraries.

At some point there will not be a HtmlHelper that does just what is needed and want to share a few examples of customer HtmlHelpers.

Example 1. Label Helper
This example generates html label page elements. Creating the label is as simple as building a string containing the html to be displayed on the page.

using System.Web.Mvc;

namespace HtmlHelpersDemo.Code
{
    public static class Helpers
    {
        public static MvcHtmlString Label(string labelText)
        {
            return new MvcHtmlString(string.Format("<label>{0}</label>", labelText));
        }

        public static MvcHtmlString Label(string labelText, string forAssociatdControl)
        {
            return new MvcHtmlString(string.Format("<label for='{0}'>{1}</label>", forAssociatdControl, labelText));
        }
    }
}

These methods return an instance of type MvcHtmlString class which represents an HTML-encoded string. MvcHtmlString is a member of System.Web.Mvc namespace (in System.Web.Mvc.dll).

Usage
To display a label we add a using statement at the beginning of our view.

@using HtmlHelpersDemo.Code;
@{
    ViewBag.Title = "Home Page";
}

@Helpers.Label("First Name:")

@Helpers.Label("Last Name:", "SomeControl")

When rendered the page contains the labels as expected.
html-helper-label-code

This is quite a simple example but the method could be applied to creating a html table row or even the whole table.