ASP.NET AJAX:Registering your script during a partial postback call
By now, everyone knows that you should use the RegisterXXX methods of the ScriptManager class to insert a script block during a partial postback (that is, when you're using ASP.NET AJAX and UpdatePanels). Even though this is "common knowledge", what most don't know is that using one of those methods and associating a script block with a page (ie, passing a reference to the page object as the first parameter od a method) might not be enough for inserting the script on the page. Lets run a small example:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
manager.RegisterAsyncPostBackControl(bt);
}
void InsertScript(Object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript( this, this.GetType(), "hello", "alert('hello');", true);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" id="manager" />
<asp:UpdatePanel runat="server" id="panel" UpdateMode="Conditional">
<contenttemplate>
<%= DateTime.Now.ToString() %>
</contenttemplate>
</asp:UpdatePanel>
<asp:Button runat="server" ID="bt" Text="start partial postback" OnClick="InsertScript" />
</form>
</body>
</html>
If you run this code, you won't get the alert message. If you remove the UpdatePanel or if you set its update mode to Always, then it'll start working. Why? well, because in the current version you're only able to insert a script on a page during a partial postback if:
- there aren't any UpdatePanel controls on a page;
- you've associated the script with a control placed on an UpdatePanel that is being refreshed;
- you've associated the control with a page and there exists at least an UpdatePanel that is getting refreshed.
In the previous example, we've associated the script with the page, but notice that the only UpdatePanel that is on the page won't be refreshed since its mode is set to Conditional and the control that started the partial postback isn't registered as trigger nor did we call its Refresh method during the postback. So, if setting the UpdateMode property of the panel to Always is overkill, the only thing I think you can do (that is, if you can't wait for the next version of the platform :) ) is add an empty UpdatePanel to the page and set its Visible property to false (and that should garantee that your scripts are always injected on the page).