Introduction
In my previous article, I explained how to partially render pages in ASP.NET 2.0 and ATLAS with client script. In this article, I will try to help you troubleshoot a series of common errors when you implement the ICallbackEventHandler
and IPostBackEventHandler
interfaces. To be precise, for each error, I added a sample code to generate the problem and also necessary code that helps you to eliminate the problem.
Using the Code
Error: ‘theForm._EVENTTARGET’ is null or not an object (Applies to: ASP.NET - ATLAS)
This error may appear because of the way you dynamically manipulate your HTML document. If you use non-W3C standard Document Object Model (DOM) methods to dynamically manipulate your document, expect this problem to happen. A good example of this is when you use the non-standard “innerHTML
” property of your objects. This may pose a huge compatibility issue with your existing JavaScript code. Hopefully, ASP.NET adds support for non-standard methods and properties, but until then, you need to revise your JavaScript code. I could not find any documentation that shows this behavior by design, therefore, possibly it is a bug.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
public partial class CallbackSample : System.Web.UI.Page, ICallbackEventHandler
{
static int i;
string strMessagetoClient;
protected void Page_Load(object sender, EventArgs e)
{
strMessagetoClient = "";
if (IsCallback)
{
i++;
Label1.Text = "I am lost";
strMessagetoClient = String.Format("For the {1} " +
"time Callback raised at {0}.",
DateTime.Now.TimeOfDay.ToString(),
i.ToString());
}
else if (!IsPostBack)
{
i = 0;
ClientScriptPlumbing();
}
Calendar1.SelectedDate = DateTime.Today.AddDays(i);
Label1.Text = String.Format("Total number" +
" of Callbacks:{0}", i.ToString());
ClientScriptPlumbing();
}
private void ClientScriptPlumbing()
{
string functionRef = Page.ClientScript.GetCallbackEventReference(this,
"args", "getServerData",
"'this is context from server'");
string strCallback = "function CallServer(args," +
"context){" + functionRef + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallServer", strCallback, true);
Page.ClientScript.RegisterClientScriptBlock(
this.GetType(), "CommonScripts", @"
function btnBug_onclick() {
CallServer('Hi','Client Call');
// non-standard
document.body.innerHTML+='<P style=\'color:red;\' > ' +
'From this point, the postback from' +
' controls doesnt work. Try the Calendar!(to'+
'resolve this issue comment this line ' +
'of JS and use the DOM version )<P>';
//standard
//uncomment the lines below and comment the above line
/*
newDiv = document.createElement('div');
newDiv.id='newDiv';
var mytext=document.createTextNode('I was added' +
' dynamically but unlike innerHTML' +
' I dont harm your Calendar Postbacks. Use DOM!');
newDiv.appendChild(mytext);
document.body.appendChild(newDiv);*/
}
//Clicking on Button1 makes a Callback
//and triggers RaiseCallbackEvent
function Button1_onclick()
{
CallServer('Hi','Client Call');
return false;
}
// Receive the string returned by GetCallbackResult
function getServerData(args, context)
{
myCustomFunc(args);
}
// My JS scripts that takes care of partial rendering
function myCustomFunc(strArgs)
{
var NewTxtArea= document.getElementById('NewTxtArea');
if (!NewTxtArea )
{
var NewTxtArea = document.createElement('textarea');
NewTxtArea.id = 'NewTxtArea';
NewTxtArea.rows = 10;
NewTxtArea.cols = 100;
document.body.appendChild(NewTxtArea);
}
NewTxtArea.value+=strArgs + '\n';
}
"
, true);
}
public void RaiseCallbackEvent(string eventArgument)
{
Label1.Text = "This text is never shown!!!";
strMessagetoClient += "The server side is updated," +
" but I am just a javascript " +
"and too lazy to update your calendar.";
strMessagetoClient += "To update do a Postback " +
"by clicking on the calendar .";
}
public string GetCallbackResult()
{
return strMessagetoClient;
}
}
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="_EVENTTARGETisNullError .aspx.cs"
Inherits="CallbackSample" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>www.themorningoutline.com</title>
</head>
<body id='myBody'>
<form id="form1" runat="server">
<asp:Label ID="Label1" runat="server"
Height="8px" Text="Callback"
Width="255px">
</asp:Label>
<asp:Calendar ID="Calendar1"
runat="server"></asp:Calendar>
<input id="Button1" language="javascript"
onclick="return Button1_onclick()"
type="button" value="Callback" />
<input id="btnBug" type="button" value="Bug me!"
language="javascript"
onclick="return btnBug_onclick()" /><br />
</form>
</body>
</html>
Error: ‘_pendingCallbacks[...].async’ is null or not an object (Applies to: ASP.NET – ATLAS)
This error appears when a JavaScript function, which is called by GetCallbackResult
, utilizes a variable called ‘i
’. This bug was fist discussed back in 2005 in the comment section of a post from Rick Strahl's Web Log called "Script Callbacks in ASP.NET 2.0 interface changes in Visual Studio July CTP" and it exists until today. Apparently, “i
” is declared as a global variable in ASP implementation, and by changing it, you are messing with ASP.NET auto-generated scripts. To resolve this problem, declare your variable as a local variable in the function.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
public partial class PostbackSample : System.Web.UI.Page,
ICallbackEventHandler, IPostBackEventHandler
{
static int i;
static int j;
string strMessagetoClient;
static string CallbackTime;
protected void Page_Load(object sender, EventArgs e)
{
strMessagetoClient = "";
if (IsCallback)
{
i++;
CallbackTime = DateTime.Now.TimeOfDay.ToString();
strMessagetoClient = String.Format("For the {1} time" +
" Callback raised at {0}.",
CallbackTime, i.ToString());
Label1.Text = "I am lost";
}
else if (IsPostBack)
{
j++;
ClientScriptPlumbing();
}
else
{
i = 0;
CallbackTime = "Not Yet";
ClientScriptPlumbing();
}
Calendar1.SelectedDate = DateTime.Today.AddDays(i);
Label1.Text = String.Format("Total Callbacks count:{0}" +
" Last Callback Occurred at {1}",
i.ToString(), CallbackTime);
}
private void ClientScriptPlumbing()
{
string functionRef = Page.ClientScript.GetCallbackEventReference(this,
"args", "getServerData",
"'this is context from server'");
string strCallback = "function CallServer(args,context){" +
functionRef + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallServer", strCallback, true);
functionRef = Page.ClientScript.GetPostBackClientHyperlink(this,
"PostBack");
string strPostBack = "function PostServer(args,context){" +
functionRef + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"PostServer", strPostBack, true);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CommonScripts", @"
var INeedABug=false;
function btnBugATLAS_onclick() {
INeedABug=true;
newDiv = document.createElement('div');
newDiv.id='newDiv';
var mytext=document.createTextNode('To resovle this issue' +
' uncomment the var i line' +
' in getServerData function' );
newDiv.appendChild(mytext);
document.body.appendChild(newDiv);
CallServer('bug!','Client Callback');
}
function Button1_onclick()
{
CallServer('Hi','Client Callback');
return false;
}
function Button2_onclick()
{
PostServer('Hi','ClientPostback');
return false;
}
function getServerData(args, context)
{
//uncomment this to resolve the issue
// var i
myCustomFunc(args);
if (INeedABug) i++;
}
function myCustomFunc(strArgs)
{
var NewTxtArea= document.getElementById('NewTxtArea');
if (!NewTxtArea )
{
var NewTxtArea = document.createElement('textarea');
NewTxtArea.id = 'NewTxtArea';
NewTxtArea.rows = 10;
NewTxtArea.cols = 100;
document.body.appendChild(NewTxtArea);
}
NewTxtArea.value+=strArgs + '\n';
}
"
, true);
}
public void RaiseCallbackEvent(string eventArgument)
{
Label1.Text = "This text is never shown!!!";
strMessagetoClient += "The server side is updated, " +
"but I am just a javascript " +
"and too lazy to update your " +
"calenadr, ask Postback to do it.";
}
public string GetCallbackResult()
{
return strMessagetoClient;
}
public void RaisePostBackEvent(string str)
{
Calendar2.SelectedDate = DateTime.Today.AddDays(j);
Label2.Text = String.Format("Total Postback count:{0}" +
" Last Postback Occurred at {1}", j.ToString(),
DateTime.Now.TimeOfDay.ToString());
}
}
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="_pendingCallbacksError.aspx.cs"
Inherits="PostbackSample" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>www.themorningoutline.com</title>
</head>
<body id='myBody'>
<form id="form1" runat="server">
<atlas:ScriptManager ID="ScriptManager1"
runat="server" EnablePartialRendering="True">
</atlas:ScriptManager>
<div>
</div>
<atlas:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"
Text="Callback" Height="8px" Width="505px"></asp:Label>
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
<asp:Label ID="Label2" runat="server"
Text="PostBack" Width="504px"></asp:Label>
<asp:Calendar ID="Calendar2" runat="server"></asp:Calendar>
<input id="Button1" language="javascript"
onclick="return Button1_onclick()"
type="button" value="Callback" />
<input id="Button2" language="javascript"
onclick="return Button2_onclick()"
type="button" value="Postback" />
<input id="Button3" language="javascript"
onclick="return btnBugATLAS_onclick()"
type="button" value="Bug me!" /><br />
</ContentTemplate>
</atlas:UpdatePanel>
</form>
</body>
</html>
Error: JavaScript alert “unknown error” (Applies to: ATLAS)
This error may appear when you are dealing with string
s that contain tags in your JavaScript and you place your JavaScript in the head
section or a separate file. Also, if you have any other tags that are not properly closed, you may get this error. To resolve this problem, always put your JavaScript code inside <!-- -->
, or better use the ClientScript
object of ASP.NET to register your JavaScript functions. You are very prone to get this error if you are dealing with XML in your JavaScript code.
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>www.themorningoutline.com</title>
<script type='text/javascript'>
to the body to get rid of unknown error
function genXML()
{
var strArgs= '<?xml version=\'1.0\' standalone=\'yes\'?>'
strArgs += '<Callback>'
strArgs += '</Callback>'
return strArgs;
}
</script>
</head>
<body id='myBody'>
<form id="form1" runat="server">
<atlas:ScriptManager ID="ScriptManager1"
runat="server" EnablePartialRendering="True">
</atlas:ScriptManager>
<div>
</div>
<atlas:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Calendar ID="Calendar1" runat="server">
</asp:Calendar>
Click the calndar for an unknown error!
</ContentTemplate>
</atlas:UpdatePanel>
</form>
</body>
</html>
Error: Your Callbacks/Postbacks stop working after the first successful Postback (Applies to ATLAS)
This problem may happen when your client scripts are not properly registered back on the client after ATLAS makes a partial postback. To resolve this problem, use the ClientScript
object in the Page_Load
event to register your client scripts.
protected void Page_Load(object sender, EventArgs e)
{
if (IsCallback)
{
}
else if (IsPostBack)
{
ClientScriptPlumbing();
}
else
{
ClientScriptPlumbing();
}
}
private void ClientScriptPlumbing()
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CommonScripts", @"
function foo() {}
....
"
, true);
}
Conclusion
This article explained how to resolve some of the common issues with ASP.NET ATLAS and client calls. Later in another article, I will discuss the new ATLAS text/xml-script and the ControlExtender
toolkit. I will give you some ideas about how to use JavaScript to achieve the same functionality in an easy and comprehensive fashion. You can leave your comments here.
Cheers!