Friday, 4 December 2015

IsPostBack in asp.net

IsPostBack is a Page level property, that can be used to determine whether the page is being loaded in response to a client postback, or if it is being loaded and accessed for the first time. 

In real time there are many situations where IsPostBack property is used. For example, consider the webform used to register employee details. A sample form that we will use for this example is shown below. The form has First Name, Last Name and City fields.  

If you want to follow along with me, copy and paste the following HTML in a web form.
<table style="font-family: Arial">
    <tr>
        <td colspan = "2"><b>Employee Details Form</b></td>
    </tr>
    <tr>
        <td>First Name: </td>
        <td> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> </td>
    </tr>
    <tr>
        <td>Last Name: </td>
        <td> <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox> </td>
    </tr>
    <tr>
        <td>City:</td>
        <td>
            <asp:DropDownList ID="ddlCity" runat="server">
            </asp:DropDownList>
        </td>
    </tr>
    <tr>
        <td></td>
        <td>
            <asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
                Text="Register Employee" />
        </td>
    </tr>
</table>

Copy and Paste the following code in the code behind file of the web form.
protected void Page_Load(object sender, EventArgs e)
{
    LoadCityDropDownList();
}
public void LoadCityDropDownList()
{
    ListItem li1 = new ListItem("London");
    ddlCity.Items.Add(li1);

    ListItem li2 = new ListItem("Sydney");
    ddlCity.Items.Add(li2);

    ListItem li3 = new ListItem("Mumbai");
    ddlCity.Items.Add(li3);
}
protected void Button1_Click(object sender, EventArgs e)
{
} 

Now run the application. Look at the City DropDownList. The cities, (London, Sydney and Mumbai) are correctly shown as expected. Just click the button once. Notice, that the city names in the DropDownList are duplicated. So, every time you click the button, the city names are again added to the DropDownList.

Let's now understand the cause for this duplication.
We know that all ASP.NET server controls retain their state across postback. These controls make use of ViewState. So, the first time, when the webform load. the cities get correctly added to the DropDownList and sent back to the client.

Now, when the client clicks the button control, and the 
webform is posted back to the server for processing. During the Page initialization, ViewState restoration happens. During this stage, the city names are retrieved from the viewstate and added to the DropDownList. PageLoad event happens later in the life cycle of the webform. During page load we are again adding another set of cities. Hence, the duplication.

How to solve the DropDownList items duplication
There are several ways to solve this. One of the best ways to do this, is to use IsPostBack property. So, in the Page_Load, call LoadCityDropDownList() method, if the request, is not a postback request. That is, only if the webform is being loaded and accessed for the first time.
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        LoadCityDropDownList();
    }
}

Another way to solve, this problem is to simply disable the ViewState of the DropDownlist control. To disable the viewstate, right click the DropDownList control, and set EnableViewState property to false. Now run the project, and the cities duplication issue is gone.

But the problem, with 
this approach is that, the DropDownList list, does not remember your selecttion across postback. That is, Select "Mumabi" as the city, and submit the form. When the page rerenders, observer that selection is set back to "London". Another problem with, disabling the viewstate is that, the DropDownList events may not work correctly as expected.

Another way to solve this, is to clear all the DropDownList items, before calling LoadCityDropDownList() method. But this not efficient from a performance perspective. The modified code is shown below.
protected void Page_Load(object sender, EventArgs e)
{
    ddlCity.Items.Clear();
    LoadCityDropDownList();
} 


No comments:

Post a Comment