Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Troubleshooting Partial Rendering Errors in ATLAS and ASP.NET 2.0

3.80/5 (3 votes)
24 Sep 2006CPOL3 min read 1   189  
This article helps you resolve some common errors in ASP.NET 2.0 and ATLAS.

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.

C#
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;

//@ I encourage you to use this sample code!
//@ This sample is provided under the terms of the GNU General Public License.
//@ for more information visit my blog at TheMorningOutline.com. Cheers!
//@ Shahin
// Implement ICallbackEventHandler
public partial class CallbackSample : System.Web.UI.Page, ICallbackEventHandler
{
    //Callback Counter
    static int i;
    string strMessagetoClient;
    protected void Page_Load(object sender, EventArgs e)
    {
        strMessagetoClient = "";
        if (IsCallback)
        {
            i++;
            // if you make any client side changes here,
            // they are lost and never will be shown
            Label1.Text = "I am lost";
            // Keep track of my Callback time
            strMessagetoClient = String.Format("For the {1} " + 
                                 "time Callback raised at {0}.", 
                                 DateTime.Now.TimeOfDay.ToString(), 
                                 i.ToString());
        }
        // Make sure a Postback doesn't get here
        else if (!IsPostBack)
        {
            // Initilize the Application 
            i = 0;
            // Javascript Plumbing. You only need to
            // this when the page loads for the first time 
            //if you have NO other Postbacks
            ClientScriptPlumbing();
        }
        // Make changes to the calendar. After a postback
        // you can see the calendar changes. 
        // click on the dummy postback button
        // to cause a full postback
        Calendar1.SelectedDate = DateTime.Today.AddDays(i);
        Label1.Text = String.Format("Total number" + 
                      " of Callbacks:{0}", i.ToString());
        ClientScriptPlumbing();
    }
    private void ClientScriptPlumbing()
    {
        // Get a reference of Javasctipt Callback function
        string functionRef = Page.ClientScript.GetCallbackEventReference(this, 
                             "args", "getServerData", 
                             "'this is context from server'");
        // Make a custm function to call it
        string strCallback = "function CallServer(args," + 
                             "context){" + functionRef + ";}";
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                          "CallServer", strCallback, true);
        //Register other client functions
        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);
    }

    //This is called by CallServer Javascript
    public void RaiseCallbackEvent(string eventArgument)
    {
        // Notice that the any changes you make to webcontrols won't get rendered
        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 .";
    }
    //Retrun strMessagetoClient to the clinet. 
    //Notice that it does not refresh your page
    //but it calls the registered javascript getServerData function
    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.

C#
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;

//@ I encourage you to use this sample code!
//@ This sample is provided under the terms of the GNU General Public License.
//@ for  more information visit my blog at TheMorningOutline.com. Cheers!
//@ Shahin
// Implement ICallbackEventHandler and IPostBackEventHandler
public partial class PostbackSample : System.Web.UI.Page, 
               ICallbackEventHandler, IPostBackEventHandler
{
    //Callback Counter

    static int i;
    //Postback Counter

    static int j;
    string strMessagetoClient;
    static string CallbackTime;
    protected void Page_Load(object sender, EventArgs e)
    {
        strMessagetoClient = "";
        if (IsCallback)
        {
            i++;
            // Keep track of my Callback time

            CallbackTime = DateTime.Now.TimeOfDay.ToString();
            strMessagetoClient = String.Format("For the {1} time" + 
                                 " Callback raised at {0}.", 
                                 CallbackTime, i.ToString());
            // if you make any clinet side changes here,
            // they are lost and never be shown

            Label1.Text = "I am lost";
        }
        else if (IsPostBack)
        {
            j++;
            // Javascript Plumbing. Normally You would
            // do this in your initial load and
            // RaisePostBackEvent but because Atlas oesn't
            // raise that event you need    
            // to put it here for Atlas partial Postbacks
            ClientScriptPlumbing();
        }
        else
        {
            // Initilize the Application
            i = 0;
            CallbackTime = "Not Yet";
            ClientScriptPlumbing();
        }

        // When a Postback occurs it will take care of Callback UI changes
        // if you want to make UI changes during a Callback and later show them
        // by a postback you must put them in Page_load event here

        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()
    {
        // Get a reference of Javasctipt Callback function
        string functionRef = Page.ClientScript.GetCallbackEventReference(this, 
                             "args", "getServerData", 
                             "'this is context from server'");
        // Make a custom function to call it
        string strCallback = "function CallServer(args,context){" + 
                             functionRef + ";}";
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                                  "CallServer", strCallback, true);
        // Get a reference of Javasctipt Postback function
        functionRef = Page.ClientScript.GetPostBackClientHyperlink(this, 
                                                            "PostBack");
        // Make a custm function to call it
        string strPostBack = "function PostServer(args,context){" + 
                             functionRef + ";}";
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                                  "PostServer", strPostBack, true);
        //Register other client functions
        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);
    }

    //This is called by CallServer Javascript

    public void RaiseCallbackEvent(string eventArgument)
    {
        // Notice that any changes you make  here,  won't
        // get rendered

        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.";
    }
    //Retrun strMessagetoClient to getServerData. 
    //Notice that this does not refresh your page but it calls
    //the registered javascript getServerData function
    public string GetCallbackResult()
    {
        return strMessagetoClient;
    }

    //This is called by PostServer Javascript and 
    //can be used to force UpdatePanel to refresh
    public void RaisePostBackEvent(string str)
    {
        // Your client side changes here will get rendered
        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 strings 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.

ASP.NET
<%@ 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'>
//@ TheMorningOutline.com provided this under the terms of the GNU GPL.

//Put the following function within <!--  --> or move it 

                    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.

C#
protected void Page_Load(object sender, EventArgs e)
{
    if (IsCallback)
    {
        // You don't need to re-register your
        // scripts on each Callback
        // For Callbacks,you only do it when
        // you page loads the first time.
    }
    else if (IsPostBack)
    {
        //  Normally You would do your JavaScript
        //  Plumbingthis in your initial load and
        //  RaisePostBackEvent but because Atlas
        //  doesn't raise that event you need 
        //  to put it here for Atlas partial Postbacks

        ClientScriptPlumbing();
    }
    else
    {
        // Initilize the Page
        ClientScriptPlumbing();
    }
}
private void ClientScriptPlumbing()
{
    //Register other client functions
    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!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)