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 !!!

How to create a single border table with help of CSS

When I was new with CSS, I found it very difficult to create a single bordered excel like tables. Most of the time my tables look like this:-



So I learned a trick through which I can get a smooth 1px border quite easily. Here is the CSS which I use to create good looking tables.

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        table, td, th
        {
            border: 1px solid #A0A0A0; /*Border Color*/
            border-collapse: collapse; 
        }
        th
        {
            background-color: #0875CC;/*Background color of Header*/
            color: white;/*Font Color of Header*/
            border-collapse: collapse;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table cellpadding="4">
            <tr>
                <th>
                    First Name
                </th>
                <th>
                    Last Name
                </th>
                <th>
                    Age
                </th>
            </tr>
            <tr>
                <td>Zeeshan</td>
                <td>Umar</td>
                <td>29</td>
            </tr>
            <tr>
                <td>Hassan</td>
                <td>Hamayoun</td>
                <td>25</td>
            </tr>
            <tr>
                <td>Muhamamd</td>
                <td>Arshad</td>
                <td>49</td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

Here is how above code's output looks like on browser:-


First Name

Last Name

Age
Zeeshan Umar 29
Hassan Hamayoun 25
Muhamamd Arshad 49

Feel free to share your comments. Happy Coding !!!