Sometimes, you don’t get to choose between WebForms and MVC (for instance when you’re doing some rework on an old project).
So I got stuck on a WebForms project and I’m more a MVC kinda guy.
Some reasons why I like MVC over WebForms:

  • Flexibility
  • Unit testable
  • Stateless
  • Clean html output

Some people say that you have to write more html with MVC, but I don’t really agree. When you make good use of the HtmlExtensions, DisplayTemplates and EditorTemplates, it is just the same and even more flexible.
But that’s not what this post is about.
When I was working on this WebForms project, I was creating a page with multiple UpdatePanels and that’s when the trouble started.
I wanted to update the UpdatePanel form outside the UpdatePanel, so there was no use in defining triggers. The trigger was coming from a JavaScript function.
After doing some research, I read about the __doPostBack function. This function allows you to update an UpdatePanel and takes two arguments. The first argument is the ClientID of the UpdatePanel:

<asp:UpdatePanel runat="server" ID="upDemo">
  <ContentTemplate>
    <h1>Inside the UpdatePanel</h1>
  </ContentTemplate>
</asp:UpdatePanel>

The following JavaScript code will trigger an update of the UpdatePanel in the demo above:

__doPostBack("<%= upDemo.ClientID %>", "some argument");

The second argument of the __doPostBack function is the event argument. This is a very nice feature, because this allows you to send an ID or some extra data. You can even send a json object if you want.

But now we need to intercept the data in the code behind. The __doPostBack causes a PostBack so all events of the page cycle will occur.  In the page load we can intercept the ajax event.

First of all, there is the ScriptManager. This manager handles the Ajax requests and provides useful data.

protected void Page_Load(object sender, EventArgs e)
{
  var scriptmanager = ScriptManager.GetCurrent(this);
  var isAjaxRequest - scriptmanager.IsInAsyncPostBack;
}

This code example shows how the ScriptManager exposes the IsInAsyncPostBack property. This property helps to determine if the request is an ajax request (Similar to Request.IsAjaxRequest in MVC). But what if you have more than one UpdatePanel? Which panel is causing the ajax request?
I found two ways to determine this, The first one is again the ScriptManager:

protected void Page_Load(object sender, EventArgs e)
{
  var scriptmanager = ScriptManager.GetCurrent(this);
  if (scriptmanager.IsInAsyncPostBack
   && scriptmanager.AsyncPostBackSourceElementID == upDemo.ClientID)
  {
    // we now know that the postback is caused by the upDemo UpdatePanel
  }
}

The AsyncPostBackSourceElementID holds the ClientID of the UpdatePanel which caused the PostBack.
The second way is by using  the Form values from the Request:

protected void Page_Load(object sender, EventArgs e)
{
  var target = this.Request.Form["__EVENTTARGET"];
  var scriptmanager = ScriptManager.GetCurrent(this);
  if (scriptmanager.IsInAsyncPostBack && target == upDemo.ClientID)
  {
    // we now know that the postback is caused by the upDemo UpdatePanel
    var argument = this.Request.Form["__EVENTARGUMENT"];
    // argument is the second argument of the __doPostBack function.
  }
}

The Form key __EVENTTARGET holds the ClientID of the UpdatePanel, similar to the AsyncPostBackSourceElementID

The Form key __EVENTARGUMENT holds the second argument of the __doPostBack function. When the __doPostBack function is called with only one argument, the value in __EVENTARGUMENT can be something like “undefined”. This depends on the browser. I recommend to send an empty string as second argument when no data is required for the request.

Check my follow up post here

The following two tabs change content below.
I'm a software developer from Utrecht. Interested in DDD, continuous delivery, new technologies & frameworks.

Latest posts by Vincent Keizer (see all)