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!
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.