How to dynamically change connection string in web.config

Most of people wonder how they can dynamically change the contents of web.config file. To simplify things I have created couple of functions through which you can change the contents of web.config file. Here is the code to change the contents of web.config file:-
/// <summary>
/// Updates the setting.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public void UpdateSetting(string key, string value)
{
    Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
    if (config.AppSettings.Settings[key] == null)
    {
        config.AppSettings.Settings.Add(key, value);
    }
    else
    {
        config.AppSettings.Settings[key].Value = value;
    }
    config.Save();
    ConfigurationManager.RefreshSection("appSettings");
}

/// <summary>
/// Updates the connection string.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public void UpdateConnectionString(string key, string value)
{
    Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
    if (config.ConnectionStrings.ConnectionStrings[key] == null)
    {
        config.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings(key, value));
    }
    else
    {
        config.ConnectionStrings.ConnectionStrings[key].ConnectionString = value;
    }
    config.Save();
    ConfigurationManager.RefreshSection("connectionStrings");
}

You can update the contents of web.cofig file by simply calling above functions like this:-
protected void Page_Load(object sender, EventArgs e)
{
    UpdateSetting("test", "123");
    UpdateConnectionString("testcon", "12345");
}

Unable to find the requested .Net Framework Data Provider. It may not be installed

Hi guys, I was on my holidays and enjoying something different so I was away for some time. However right now I am back and working on a Sliver light project. In that project I found an interesting situation which I would like to share with you. I was using Enterprise Library 5.0 for my connection string and I was using Oracle.DataAccess for my connection.

Here was the line on which I was getting error:-
dbase = DatabaseFactory.CreateDatabase("MyDB");


After spending some time I checked that every thing seems OK and there is no issue with my web.config file. I tried to replace CreateDatabase and use another way to create database connection in Enterprise Library:-
DbProviderFactory providerFactory =
DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
dbase = new Microsoft.Practices.EnterpriseLibrary.Data
.GenericDatabase("data source=xxx;User id=xxx;Password=xxx;",providerFactory);

Above also did not solved my problem and I started to get another error :-

I checked that either I have installed ODP or not but It was installed in my GAC folder (usually at C:\Windows\assembly). Here is how my GAC folder looks like:-

Now finally I had a clue that what happened. My system have multiple versions of Oracle.DataAccess installed and .net can not decide that which version should be used. So, to Resolve this I have to add a DbProviderFactory in my web.config file. So here is how I added it:-
 <system.data>
    <DbProviderFactories>
    <add name="Oracle Data Provider for .NET"
            invariant="Oracle.DataAccess.Client"
            description="Oracle Data Provider for .NET"
            type="Oracle.DataAccess.Client.OracleClientFactory,
                  Oracle.DataAccess,
                  Version=2.112.1.2,
                  Culture=neutral,
                  PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>

Now last thing, I know that I have to use Oracle.DataAccess but how did I get other information i.e. Version, Culture and PublicKeyToken. To do this simply right click on the Assembly and take it properties. Here is the page that will appear through which you can get all the details:-

Finally my application started working and it connected to database perfectly. Hopefully this will also be useful for you . Do share your comments with me. Happy coding !!!



How to create Tag Cloud, Word Cloud or Weighted List

Tag Cloud, Word Cloud or Weighted List is the visual representation of keywords/tags on websites that shows the importance of keyword/tag. I am sharing a simple code to generate a Tag Could. You can download whole code from this location.

First I have created list of Tags. You can use database to fetch the tags and pass them to this list:-
//Creating a list of Tags
List<string> lst = new List<string>();
lst.Add("C#");
lst.Add("C#");
lst.Add("C#");

lst.Add("Asp .Net");
lst.Add("Asp .Net");
lst.Add("Asp .Net");
lst.Add("Asp .Net");
lst.Add("Asp .Net");
lst.Add("Asp .Net");


lst.Add("Javascript");
lst.Add("Javascript");
lst.Add("Javascript");

lst.Add("Ajax");
lst.Add("Ajax");

lst.Add("jQuery");

After that I used LINQ to find group by count of individual Tag. You can also perform that step on database level if you are reading records from database:-
//Grouping tags and calculate their count using LINQ
var tags = (from l in lst
            group l by l into g
            select new { Name = g.Key, Count = g.Count() });

After that I sort the tags in descending order because normally tags are in alphabetical order.
// Sort tags in descending order
tags = (from t in tags
        orderby t.Name descending
        select t);

Here is the interesting part, here you can define minimum font size and maximum font size for tag cloud. Also I calculated the steps which will be there for minimum and maximum size.
//Minimum Size for Tags, you can set it as per your need
double minSize = 10;

//Maximum Size for Tags, you can set it as per your need
double maxSize = 20;

//Calculating the step in which increament the fonts
double steps = (maxSize - minSize) / (double)tags.Count();

Finally I am creating SPAN tags for each tag item with this code:-
StringBuilder sb = new StringBuilder();
        foreach (var tag in tags)
        {
            //Calculating the Size
            double size = minSize + ((double)tag.Count - 1) * steps;

            //Create the SPAN tag with spefic font size so it looks like cloud
            sb.Append("<span style='font-size:" + size + "pt'>" + tag.Name + " </span>");
        }

And Here is the result of my tag cloud application:-
  
This seems good but not too good to me so I changed one line from my code like this:-
//Create the SPAN tag with spefic font size so it looks like cloud
      sb.Append("<span style='font-size:" + size + "pt'>" + tag.Name + "("+ tag.Count +") </span>");

And here is the result, I get the count after every tag:-
Hopefully this will be useful for you , do share your comments on that. Happy Coding !!!

Improve ASP.Net Performance by effective utilitzation of String

Many people ask me that how they can improve their website's performance? There are many ways through which you can improve the performance of your website but today, I will discuss the performance improvement with Strings.
In my opinion String is the most frequently used data type compared to other data types available. But there is a big problem with string, it is immutable. An immutable object is an object which cannot be modified. So whenever we try to change anything with string a new string object is created. These frequent creations of objects degrade the system's policy.

Avoid using "" as empty string

Every time when you write "" a new string object is created. But if you use string.Empty it will not create any additional string before assignment.
//bad practice
string str = "";

//good practice
string str1 = string.Empty;

Avoid .ToLower()/.ToUpper() for Comparison

Usually developers heavily use .ToLower() or .ToUpper() to perform case insensitive comparison. Instead you should use string.Compare function.
//Bad Practice
string errorCode= "ec-1001";
if (errorCode.ToLower() == "ec-1001")
{

}

//good Practice
string errorCode1 = "ec-1001";
if (string.Compare( errorCode1,"ec-1001",true)==0)
{
}

Also there are situations when we can control the case of a string i.e. generally we add 'M' or 'F' for gender. Now we can ensure that throughout application we either use capital 'M' or small 'm' to define male. A good approach is to use const in such cases.
const string Male = "M";
const string Female = "F";
string myGender = Male;

Avoid multiple string concatenation

Whenever you have to modify a string many times then consider using StringBuilder instead of simple string. Every time when you modify a string, a new object would be created. However, StringBuilder is mutable object and it performs string modifications without creating multiple objects.

//Bad practice
string text = "start";
text += "start 1";
text += "start 2";
text += "start 3";
text += "start 4";
text += "start 5";

for (int i = 0; i < 10; i++)
{
    text += "text " + i;
}

//Good Practice
StringBuilder sb = new StringBuilder();
sb.Append("start");
sb.Append("start 2");
sb.Append("start 3");
sb.Append("start 4");
sb.Append("start 5");

for (int j = 0; j < 10; j++)
{
    sb.Append( "text " + j);
}

Drag and Drop in Siliverlight using Mouse

Recently I started working with Silverlight. It is really a wonderful tool from Microsoft and I am too excited about it. It gives developer the power to create impressive looking user interface. In this tutorial I will focus on drag and drop functionality in Silverlight using mouse. You can download complete source code from SilverLightMouseEvents.zip.

First create a new Silverlight Application project, here is how your project will look like:-



I have added event handlers for MouseLeftButtonDown,MouseLeftButtonUp,MouseMove and LostMouseCapture. I also added a canvax and a button in MainPage.xaml. Here is the code of MainPage.xaml after adding events:-

<UserControl x:Class="SliverLightMouseEvents.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="491" 
             MouseLeftButtonDown="UserControl_MouseLeftButtonDown" 
             MouseLeftButtonUp="UserControl_MouseLeftButtonUp" 
             MouseMove="UserControl_MouseMove" 
             LostMouseCapture="UserControl_LostMouseCapture">

    <Canvas x:Name="mainCanvas" Width="640" Height="480" >
        <Button Content="AddRectangle" Width="100" Height="30" Margin="12,258,378,12" Click="Button_Click" />
    </Canvas>
</UserControl>

On the button click I have added a rectangle to mainCanvas. Here is how it is done:-

private void Button_Click(object sender, RoutedEventArgs e)
{
    //Creating a rectangle
    Rectangle rectangle = new Rectangle()
    {
        Stroke = new SolidColorBrush(Colors.Black),
        Width = 100,
        Height = 100,
        Fill = new SolidColorBrush { Color = Color.FromArgb(200, 146, 5, 23) }
    };


    //Set its initial position
    Canvas.SetLeft(rectangle, 100);
    Canvas.SetTop(rectangle, 100);

    //Adding it to mainCanvas
    mainCanvas.Children.Add(rectangle);
}

Now first we have to handle MouseLeftButtonDown event. Here is the code:-

private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    //If mouse button is down and control on which button is pressed is rectangle
    if (e.OriginalSource.GetType() == typeof(Rectangle))
    {
        this.isMoving = true;

        //Calculate the current mouse's relative position
        clickOffset.X = e.GetPosition(mainCanvas).X - Canvas.GetLeft((Rectangle)e.OriginalSource);
        clickOffset.Y = e.GetPosition(mainCanvas).Y - Canvas.GetTop((Rectangle)e.OriginalSource);

        //Generate Mouse Events even if mouse is moved outside control's area
        CaptureMouse();
    }
}

One thing which you should remember when doing drag and drop is CaptureMouse() function. Many user will move their mouse outside your application while draging and if you do not write CaptureMouse() when mouse is outside you will recieve no events from mouse.

Now here is the code which I wrote in MouseMove event:-
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
    if (this.isMoving) //If mouse button is down
    {
        if (e.OriginalSource is Rectangle) //if control is rectangle
        {
            Rectangle rect = e.OriginalSource as Rectangle; //Get the original control

            //Changing its color so we can get the feel of selection
            rect.Fill = new SolidColorBrush { Color = Color.FromArgb(100, 146, 5, 23) };

            //Calculate the distance form initial mouse down and adjust top,left accordingly
            Canvas.SetLeft(rect, e.GetPosition(mainCanvas).X - clickOffset.X);
            Canvas.SetTop(rect, e.GetPosition(mainCanvas).Y - clickOffset.Y);
        }
    }
}

In above code, I adjusted the top,left of the Rectangle as per position of mouse.

Now when user release the mouse button, MouseLeftButtonUp event is fired. Here is the code which I written in MouseLeftButtonUp event:-

private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    //if mouse is moving
    if (this.isMoving)
    {
        //if control is rectangle on which mouse is moving
        if (e.OriginalSource is Rectangle)
        {
            //Change rectangle color back to normal
            Rectangle rect = e.OriginalSource as Rectangle;
            rect.Fill = new SolidColorBrush { Color = Color.FromArgb(200, 146, 5, 23) };
        }
        //Set moving to false
        this.isMoving = false;

        //Stop listening mouse events which are outside current control's boundary
        ReleaseMouseCapture();
    }
}

Finally here is the code of LostMouseCapture event, if you remove this code from my sample, it will behave weired when mouse goes outside control's area:-

private void UserControl_LostMouseCapture(object sender, MouseEventArgs e)
{
    if (this.isMoving)// if Previously mouse is clicked down
    {
        this.isMoving = false; //mark that mouse is now moved up
    }
}

Finally here is the output of the application:-

How to print contents of Div only

Generally we do not want to create complex report and our clients are not interested in purchasing expensive reporting tools then we can generate simple HTML based reports for them. You just have to place your report inside a< div>... < / div> and you can easily print that. Here is a sample through which you can easily print contents of specified div only:-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <script language="javascript" type="text/javascript">
        function printDiv(divID) {
            //Get the HTML of div
            var divElements = document.getElementById(divID).innerHTML; 
            //Get the HTML of whole page
            var oldPage = document.body.innerHTML;
            
            //Reset the page's HTML with div's HTML only
            document.body.innerHTML = "<html><head><title></title></head><body>" + divElements + "</body>";
            
            //Print Page
            window.print();
            
            //Restore orignal HTML
            document.body.innerHTML = oldPage;
            
            //disable postback on print button
            return false;
        }
    </script>
    <title>Div Printing Test Application by Zeeshan Umar</title>
</head>
<body>
    <form runat="server">
    <asp:Button ID="btnPrint" runat="server" Text="Print" OnClientClick="return printDiv('div_print');" />
    <div id="garbage1">I am not going to be print</div>
    <div id="div_print"><h1 style="color: Red">Only Zeeshan Umar loves Asp.Net will be printed :D</h1></div>
    <div id="garbage2">I am not going to be print</div>
    </form>
</body>


Here is the output of the page when I run the code:-



And when I pressed print button, it hide all the remaining area and only my div's contents are visible which will be printed:-


Feel free to comment if you require any clarification. Happy coding !!!

Article of the Day, XML Serilization Tutorial

On Saturday, Jul 02, 2011, my article on 'XML Serialization Tutorial' was selected as 'Article of the Day' at http://www.asp.net.



I also recommend to all of readers to do share useful articles on http://www.asp.net/community. Whenever you found an article which is interesting and can be useful for others.

How to get the week number of date

Recently I faced a problem in my project that I have 52 images and I have to display images based on the week of year. So as a solution I created images with image name like image1.jpg,image2.jpg and so on. And created a small function which returns the week of year. Here is the code through which I calculated the week of year after searching it on net for a while:-

/// <summary>

/// Gets the week number.

/// </summary>

/// <param name="dtDate">The date for which week number is required.</param>

/// <returns></returns>

public static int GetWeekNumber(DateTime dtDate)

{

    CultureInfo culture = CultureInfo.CurrentCulture;

    int weekNumber= culture.Calendar.GetWeekOfYear(dtDate, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);

    return weekNumber;

}


After this function I placed a server side Image control on my aspx page like this:-
<asp:Image ID="imgForWeek" runat="server" />

And here is how I called my function to display image for week in my code behind file:-

protected void Page_Load(object sender, EventArgs e)

{

    if (!IsPostBack)

    {

        imgForWeek.ImageUrl = "../Images/image" + GetWeekNumber(DateTime.Now)+".jpg";

    }

}


Hopefully this will be useful for you as well. Happy Coding !!!

Creating Reports in Excel 2007 using EPPlus (Header, Footer, Comments, Image, Formatting, Shape and Formula)

Introduction

EPPlus is really a powerful tool to generate excel based reports on server side and it is becoming my favorite tool as I am getting more experienced with it. Previously I wrote a post about Creating advanced Excel 2007 Reports on Server. This post is update on the last post and I am sharing more advanced feature of EP Plus.

Code which I used in this post can be downloaded from this location.

Create Excel Worksheet

First of all we have to create a worksheet, here is the function which creates a worksheet:-
private static ExcelWorksheet CreateSheet(ExcelPackage p, string sheetName)
 {
    p.Workbook.Worksheets.Add(sheetName);
    ExcelWorksheet ws = p.Workbook.Worksheets[1];
    ws.Name = sheetName; //Setting Sheet's name
    ws.Cells.Style.Font.Size = 11; //Default font size for whole sheet
    ws.Cells.Style.Font.Name = "Calibri"; //Default Font name for whole sheet

    return ws;
 }

Above code creates a worksheet and assigned name to the sheet. Also set the default font for all cells as Calibri and 11 size.

Merge Excel Columns

Now here is how you can merge several columns into one:-
//Merging cells and create a center heading for out table
ws.Cells[1, 1].Value = "Sample DataTable Export"; // Heading Name
ws.Cells[1, 1, 1, dt.Columns.Count].Merge = true; //Merge columns start and end range
ws.Cells[1, 1, 1, dt.Columns.Count].Style.Font.Bold = true; //Font should be bold
ws.Cells[1, 1, 1, dt.Columns.Count].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; // Aligmnet is center

Excel Cell Background Color

Here is how you can modify the background color of a cell:-
//Setting the background color of header cells to Gray
var fill = cell.Style.Fill;
fill.PatternType = ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(Color.Gray);

Excel Cell Border

You can set borders to cell like this:-
//Setting Top/left,right/bottom borders.
    var border = cell.Style.Border;
    border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thin;

Excel Formula

Formulas is really powerful feature of Excel. You can apply any formula through the help of EP Plus. Here is how you can add a sum formula:-

//Setting Sum Formula
cell.Formula = "Sum(" + ws.Cells[3, colIndex].Address + ":" + ws.Cells[rowIndex - 1, colIndex].Address + ")";
Note that
ws.Cells[3, colIndex].Address
give the cell Address like A1 or C10 and same address will be used when you edit a formula in Excel.

Add Comments to Excel Cell

Here is the wrapper function through which you can add comments to a cell:-
private static void AddComment(ExcelWorksheet ws, int colIndex, int rowIndex, string comment, string author)
{
    //Adding a comment to a Cell
    var commentCell = ws.Cells[rowIndex, colIndex];
    commentCell.AddComment(comment, author);
}

I tried to enter blank 'Author Name' in comments but it failed to work. So always put a 'Author Name' in comments as well.

Add Image in Excel Sheet

With the help of this function, you can add an Image to your excel sheet:-
private static void AddImage(ExcelWorksheet ws, int columnIndex, int rowIndex, string filePath)
{
    //How to Add a Image using EP Plus
    Bitmap image = new Bitmap(filePath);
    ExcelPicture picture = null;
    if (image != null)
    {
        picture = ws.Drawings.AddPicture("pic" + rowIndex.ToString() + columnIndex.ToString(), image);
        picture.From.Column = columnIndex;
        picture.From.Row = rowIndex;
        picture.From.ColumnOff = Pixel2MTU(2); //Two pixel space for better alignment
        picture.From.RowOff = Pixel2MTU(2);//Two pixel space for better alignment
        picture.SetSize(100, 100);
    }
}

Add Custom objects to Excel Sheet


Here is the function through which you can add a custom shape to your excel sheet:-
private static void AddCustomShape(ExcelWorksheet ws, int colIndex, int rowIndex, eShapeStyle shapeStyle, string text)
{
    ExcelShape shape = ws.Drawings.AddShape("cs" + rowIndex.ToString() + colIndex.ToString(), shapeStyle);
    shape.From.Column = colIndex;
    shape.From.Row = rowIndex;
    shape.From.ColumnOff = Pixel2MTU(5);
    shape.SetSize(100, 100);
    shape.RichText.Add(text);
}

Conclusion

EPPlus is really a nice library to generate creative Excel reports for demanding industry. I have tried to share what I have learned so far. See the image below showing the output of my code.Feel free to comment. Happy coding !!!

How to prevent cache issue with Images, CSS and Java scripts, a better aproach

Generally when we update images, CSS or java script (.js) files on server, browser still shows old files. This is because in first request, browser download all images, CSS and .js files. But on subsequent requests, browser load images, CSS and .js files from its cache. Here is the solution which you might found on most of blogs i.e. add a DateTime.Now.Ticks as parameter after file name like this:-
<img src='PTCL-3.jpg?websiteversion=<%=DateTime.Now.Ticks.ToString()%>' alt="Sample Image" />

This will solve your problem and you will always get updated images. But the problem with this approach is that your images, CSS and java script will be downloaded for every request which will slowdown your site's performance.

Now, here is how you can solve both the problems, Add a key in appSettings section of your wen.config file like this:-
<appSettings>
    <add key="WebsiteVersion" value="1"/>
</appSettings>

And add the parameter to your images, CSS and java script files like this:-
<img src='PTCL-3.jpg?websiteversion=<%=System.Configuration.ConfigurationSettings.AppSettings["WebsiteVersion"] %>' alt="Sample Image" />

Now whenever you change any Image, CSS or .js file you have to update the WebsiteVerion value in your web.config file.

Do share your comments, happy coding !!!

XML Serilization Tutorial

Introduction

Many people ask that how XML serialization work, how can we serialize our data to permanent storage. My objective is to save and load data in XML and avoid the complexity of DOM (Document Object Model). Also I want to drive a generalized mechanism which can be used in multiple projects without modification.
 
In this tutorial I am considering a case of Simple Invoice System. I will share different tricks through we can control how our data is serialized into XML.

Code
You can download the code from this location.

Overview of Application

I have created a simple GUI through which we can enter information related to invoice. Keep in mind that to keep things simple, I have not added any kind of validation in my code so you have to enter valid values by yourself. Here is the snapshot of the application :-


Serialization Implementation
I have implemented two methods in SerlizationExtension class which are responsible for serialization and de-serialization of data. Both methods are implemented as extension method, so they are available for every object and they also take an additional parameter for file name. Here is the code for your quick reference:-

/// <summary>
/// Summary description for SerlizationExtension
/// </summary>
public static class SerlizationExtension
{

    /// <summary>
    /// Serializes the specified object.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Object">The object.</param>
    /// <param name="fileName">Name of the file.</param>
    public static void Serialize<T>(this T Object, string fileName)
    {
        string filePath = HttpContext.Current.Server.MapPath(".") + "\\" + fileName;
        XmlSerializer s = new XmlSerializer(Object.GetType());
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            s.Serialize(writer, Object);
            writer.Close();
        }
    }

    /// <summary>
    /// Deserializes the specified object.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Object">The object.</param>
    /// <param name="fileName">Name of the file.</param>
    /// <returns></returns>
    public static T Deserialize<T>(this T Object, string fileName)
    {
        string filePath = HttpContext.Current.Server.MapPath(".") + "\\" + fileName;
        XmlSerializer s = new XmlSerializer(typeof(T));
        using (StreamReader sr = new StreamReader(filePath))
        {
            object obj = s.Deserialize(sr);
            return (T)obj;
        }
    }
}

In case you want to implement serialization in your code then you have to add above class in your project as well. Once you have added above class in your solution, you can simply call Serialize/DeSerialize. Also make sure that you add [Serializable] attribute on your class. Here is a sample that how you can call both methods:-

    /// <summary>
    /// Loads the invoice.
    /// </summary>
    private void LoadInvoice()
    {
        Invoice = Invoice.Deserialize("test.xml");
        BindInvoice();
    }

    /// <summary>
    /// Saves the invoice.
    /// </summary>
    private void SaveInvoice()
    {
        Invoice.Serialize("test.xml");
    }

Scenario 1
Here is the copy of InvoiceMaster and InvoiceDetail class:-

/// <summary>
/// Summary description for InvoiceMaster
/// </summary>
[Serializable]
public class InvoiceMaster
{
    public int InvoiceID { get; set; }
    public string CustomerName { get; set; }
    public DateTime IssueDate { get; set; }

    public List<InvoiceDetail> Childs { get; set; }

    public decimal TotalPrice
    {
        get
        {
            return (from l in Childs select l.SubTotal).Sum();
        }
    }

    public InvoiceMaster()
    {
        Childs = new List<InvoiceDetail>();
    }
}

/// <summary>
/// Summary description for InvoiceDetail
/// </summary>
///
[Serializable]
public class InvoiceDetail
{
    public string ItemName { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
    public decimal SubTotal { get { return ((decimal)Quantity) * Price; } }
}

Here is the sample output of test.xml which is generated with above classes:-

<?xml version="1.0" encoding="utf-8"?>
<InvoiceMaster xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <InvoiceID>1</InvoiceID>
  <CustomerName>Zeeshan Umar</CustomerName>
  <IssueDate>2011-01-01T00:00:00</IssueDate>
  <Childs>
    <InvoiceDetail>
      <ItemName>Pepsi 500ml</ItemName>
      <Price>40</Price>
      <Quantity>2</Quantity>
    </InvoiceDetail>
    <InvoiceDetail>
      <ItemName>Marinda 500ml</ItemName>
      <Price>40</Price>
      <Quantity>1</Quantity>
    </InvoiceDetail>
    <InvoiceDetail>
      <ItemName>Dew 500ml</ItemName>
      <Price>40</Price>
      <Quantity>1</Quantity>
    </InvoiceDetail>
  </Childs>
</InvoiceMaster>

Scenario 2
Although XML is generated with simply adding [Serializable] tags. But sometimes we want to serialize properties as attributes in XML rather than element. To do this I have modified my classes little bit. Here is the updated code for my classes:-

/// <summary>
/// Summary description for InvoiceMaster
/// </summary>
[Serializable]
[XmlRoot("Master")]
public class InvoiceMaster
{
    [XmlAttribute("ID")]
    public int InvoiceID { get; set; }

    [XmlAttribute("CustomerName")]
    public string CustomerName { get; set; }

    [XmlAttribute("IssueDate")]
    public DateTime IssueDate { get; set; }

    [XmlArray("Details")]
    public List<InvoiceDetail> Childs { get; set; }

    [XmlIgnore]
    public decimal TotalPrice
    {
        get
        {
            return (from l in Childs select l.SubTotal).Sum();
        }
    }

    public InvoiceMaster()
    {
        Childs = new List<InvoiceDetail>();
    }
}

/// <summary>
/// Summary description for InvoiceDetail
/// </summary>
[Serializable]
public class InvoiceDetail
{
    [XmlAttribute("Name")]
    public string ItemName { get; set; }

    [XmlAttribute("Price")]
    public decimal Price { get; set; }

    [XmlAttribute("Quantity")]
    public int Quantity { get; set; }

    [XmlIgnore]
    public decimal SubTotal { get { return ((decimal)Quantity) * Price; } }
}

Here is the XML generated with above classes:-

<?xml version="1.0" encoding="utf-8"?>
<Master xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="0" CustomerName="" IssueDate="0001-01-01T00:00:00">
  <Details>
    <InvoiceDetail Name="Pepsi" Price="1" Quantity="40" />
    <InvoiceDetail Name="Coke" Price="2" Quantity="40" />
    <InvoiceDetail Name="Dew" Price="2" Quantity="40" />
  </Details>
</Master>

As you can see this time XML is quite simple, short and more readable compared with previous scenario. I have added [XmlAttribute()] attribute on the properties which mean that properties will be added as attribute in XML. Also I have specified [XmlIgnore] attribute on those properties which I dont want to serilize. Note that readonly properties can not be serilized and it is better to add [XmlIgnore] attribute on those properties.

Conclusion
We have seen in above samples that how we can take advantage of serialization mechanism provided by .Net. In this tutorial I have tried to keep things as simple as possible so you can understand the basic concepts of XML serialization. Feel free to share your comments. Happy Coding !!!