Friday, December 26, 2008

How to determine the control that caused PostBack in an ASP.NET Page?

I have faced this issue a lot of time, where I want to know what control caused the asp.net page to postback. If you study carefully, you will find that ALL the server side asp.net controls are rendered as simple HTML to the client browser. When a postback occurs some event at the server side is triggered such as Button_Click, SelectedIndexChanged, Page_Load etc. Now let's go in some more details.. The rendered asp.net page is nothing but a plain HTML. Now when the page causes a postback, the asp.net engine needs to know what has cused the postback. Depending on this, the engine will trigger particular event on the server side. How does the asp.net engine know what control has caused postback???

If you view the source of the rendered asp.net page you would find some hidden text fields such as __EVENTTARGET, __EVENTARGUMENT, __VIEWSTATE. These fields act as information storage for the HTML page. They convey the postback infromation to the asp.net engine, which can then trigger appropriate event.

When you change the index of dropdown control or any other control, a javascript function name "__doPostBack" is invoked. This function is responsible for saving the control information along with control arguments i.e. called as EventTarget and EventArguments. The __EVENTTARGET field stores the name of the control that caused postback. Hence by simply querying this hidden field we can get the name of the control that caused postback as shown below:


string controlName = page.Request.Params.Get("__EVENTTARGET");
if (controlName != null && controlName != string.Empty)
{
return this.Page.FindControl(controlName );
}

This will work absolutely fine with TextBox, DropDown, LinkButton control, but it won't work with Button control. Since the Button control is rendered as <input type="Submit" />. The __doPostBack function is not called in this case, hence the hidden field __EVENTTARGET is not set. Now in such case how to find the control name that caused postback?

An IMPORTANT point to note is a Submit button i.e. <input type="Submit" /> is not added to the Form until it causes a postback. This means that if their are 3 buttons on the page names B1, B2 and B3. And B2 caused a postback then B1 and B3 will not be added to the form. Thus if the Button causes a postback we can definitely search it in page.Request.Form as shown below:

Control control = null;
foreach (string formControl in page.Request.Form)
{
Control ctrl = page.FindControl(formControl );
if (ctrl is System.Web.UI.WebControls.Button)
{
control = ctrl;
break;
}
}

Thus the final method to get the postback control will look like:


 public Control GetPostBackControl(Page CurrentPage)
{
Control control = null;
string controlName = page.Request.Params.Get("__EVENTTARGET");
if (controlName != null && controlName != string.Empty)
{
control this.Page.FindControl(controlName );
}
else
{

foreach (string formControl in page.Request.Form)
{
Control ctrl = page.FindControl(formControl );
if (ctrl is System.Web.UI.WebControls.Button)
{
control = ctrl;
break;
}
}
}
return control;
}

In this way we can find out the control that caused postback in asp.net.

Hope this helps :)

3 comments:

Anonymous said...

Hi sandeep...very useful article.

I just want to know whether we can write this code in global.asax.

Sandeep Aparajit said...

In Global.asax you wont get the Page object hence the Page.FindControl method wont be available. You can use the Request.Form for finding out the control that caused postback. You will have to write a recursive method that will loop through the controls in the Form object and will return the required one.
Hope this helps!

The Opening Batsman said...

ya thanks that worked...

Post a Comment