Showing posts with label UpdatePanel. Show all posts
Showing posts with label UpdatePanel. Show all posts

Wednesday, 26 January 2011

UpdatePanels - Response Text

So, I've covered the basics of UpdatePanels in a previous post but what exactly makes them so much faster than just normal postbacks? Well the answer is that when the server responds, it doesn't respond with the full HTML of the whole page, instead, it'll respond with only the HTML that it needs to be able to update the content of each UpdatePanel.

This is done using a special format that is read, understood and executed by JavaScript at the client. An example of this response text is here:


175|updatePanel|panel|
                <input name="textbox" type="text" value="Foo" id="textbox" />
                <input type="submit" name="button" value="Submit" id="button" />
            |88|hiddenField|__VIEWSTATE|/wEPDwUKMTg0NjEyNDk1MQ9kFgICAw9kFgICAQ8PFgIeB1Zpc2libGVoZGRkcMaCINs5w9oczWUhLKPVgiBR3uk=|64|hiddenField|__EVENTVALIDATION|/wEWBAKc1c6BDgKsyt74CwLz9r7ABAKw3cLDCSDRvcYZVa7GBSZW2zBXlJJG8Vsa|0|asyncPostBackControlIDs|||0|postBackControlIDs|||16|updatePanelIDs||tpanel,tpanelTwo|0|childUpdatePanelIDs|||5|panelsToRefreshIDs||pa
nel|2|asyncPostBackTimeout||90|12|formAction||Default.aspx|13|pageTitle||Untitled Page|


Now this actually has a specific format, even if it doesn't seem so at first glance. Essentially, it's a concatenation of strings, the breakdown of each string is represented in the diagram below:


In the example above, you can tell roughly, what's going to happen to the page, just by looking at the response text. The content of the update panel whose id is "panel", will be changed to now contain the textbox and submit buttons as defined by the HTML in the response text. It includes the new ViewState value, the IDs of any other update panels contained within the page, the IDs of the update panels to be refreshed and then a few other page level properties like the form action and the window title.

Now we know the format of this response text, we can make use of that knowledge if we ever need to transform our output from the server to the client. For example, you may want to remove all unnecessary white space from the response, or, you may need to change a URL reference and rather than finding each and every instance, you could just change it at the very end of the page life cycle. I'll explain how to do all of this in a future post!

Saturday, 22 January 2011

The Beauty of UpdatePanels

So, my first ever technical blog post… here goes…

UpdatePanels are, in a word, fantastic. For those of you that haven’t had the pleasure of using them before, they give an ASP.NET WebForms developer a simple way of performing AJAX calls. This allows you to update parts of your web page, requiring no page load. Which means no white flicker as the page re-renders and, more importantly, it’s faster than a full page load!

So, how do you use one?  Well, an UpdatePanel can get a little advanced, but the basics are as follows…

Firstly, you need a ScriptManager control. These things are pretty cool too, they provide the JavaScript functions needed for an UpdatePanel to work, they also allow you to use PageMethods (that’s a future blog topic) and make globalization a little easier.

Secondly, unsurprisingly, you need your UpdatePanel control. This needs to be wrapped around the content you want to update using an ajax call. So, as an example, take the following:

<asp:TextBox ID="tb" runat="server" Text="Hello" />
<asp:ScriptManager ID="scriptManager" runat="server">     
</asp:ScriptManager>
        
<asp:UpdatePanel ID="panel" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:TextBox ID="textbox" runat="server" Text="Foo" />
        <asp:Button ID="button" runat="server" Text="Submit" />
    </ContentTemplate>
</asp:UpdatePanel>

So, now, any control that causes a postback that sits inside the UpdatePanel will cause a partial page postback, using an AJAX call, and only the content of the UpdatePanel will be updated. So, using that knowledge, I'm now going to place the following handler on the click event of the button:

void button_Click(object sender, EventArgs e)
{
    this.textbox.Text += " Bar";
    this.tb.Text += " World";
}

What do you think will happen?

Yep, you're right. The TextBox outside the panel will still read "Hello" but the TextBox inside will read "Foo Bar". You'll notice that the full page life cycle still takes place, it has to to ensure the controls object gets created, however, the data sent back to the client only includes the data used to update the UpdatePanel, this leads to a significant amount of time and bandwidth saved.

Now, at first, this sounds fantastic, but it can result in a few odd errors, one of which I'll show you now. The errors stem from the problem that when you change certain properties of controls outside of the update panel you're updating, then the server expects these controls to retain these properties on postback, however, the data it's sent back from the client is still holding the old properties and so, we have a problem.

Take this example, if we change the button_Click method to this:

void button_Click(object sender, EventArgs e)
{
    this.tb.Visible = false;
}

Now, when you hit the button twice, you'll get a JavaScript error message (Assuming you have debugging turned on) which states the following:

Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

Cutting a long story short, the data sent from the client, to the server, includes a textbox that the server thinks shouldn't be there (you've just made it invisible after all.) and so, when it tries to validate the data, it fails. This can happen with other controls too, with different properties, for example, if you change the Items within a DropDownList and don't update then that can cause problems. It's just something you have to look out for. In complicated systems, it can become a bit of a pain.

Anyway, the last, very helpful feature of UpdatePanels is that you can force an update of any UpdatePanel, take this code for an example, we add an extra UpdatePanel to the code above:

<asp:UpdatePanel ID="panelTwo" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:TextBox ID="textboxTwo" runat="server" Text="Code" />
    </ContentTemplate>
</asp:UpdatePanel>

Now, if we change the button_click method to this:

void button_Click(object sender, EventArgs e)
{
    this.textbox.Text += " Bar";
    this.label.Text += " World";


    this.textboxTwo.Text += " Bye";
    this.panelTwo.Update();
}

Both UpdatePanels will be updated. It's also possible to ensure that an UpdatePanel is updated on every postback by changing the UpdateMode to Always.

Ok, that's my brief overview. I've missed out A LOT of information, some of which I'll cover in detail in future blogs but hopefully that should be enough to get you started.

Let the AJAX fun begin!


For further reading, try some of these articles:
http://msdn.microsoft.com/en-us/library/bb386454.aspx
http://msdn.microsoft.com/en-us/magazine/cc163413.aspx#S1
http://www.asp.net/ajax/tutorials/understanding-asp-net-ajax-updatepanel-triggers