ASP.NET Callback – and HOW?

If you try to find ASP.NET Callback sample from your favourite search engine, most probably you will get samples with this method.

ClientScriptManager.GetCallbackEventReference

It is correct that you have to use this method to register the javascript function to handle Callback. With this approach, I found it is not easy to manage if I want to perform Callback in multiple Web User Controls at the same page. And also, personally, I don’t like to write javascript functions in code behind files. Unless I have to. I consider this as Separation of concerns. Open-mouthed smile

By following Implementing Client Callbacks Programmatically Without Postbacks in ASP.NET Web Pages article, I found eventually the Callback method registration will end up with this javascript rendered at client side.

<script type="text/javascript">
//<![CDATA[
function CallServer(arg, context) {WebForm_DoCallback('__Page',arg,ReceiveServerData,"",null,false); }//]]>
</script>

Since thing become clear to me, so I plan to write everything in javascript file. I quickly check what is WebForm_DoCallback and what are the arguments that it demand.

function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync)

All of the arguments are pretty meaningful from the name itself. By comparing these two scripts, I found the only challenge is to figure out what is __Page? After searching & several testing, I can confirm it is UniqueID of the page/web user control. So it end up with this code in my page.

        protected void Page_Init(object sender, EventArgs e)
        {
            String script;

            if (!Page.IsCallback)
            {
                Page.ClientScript.GetCallbackEventReference(this, "", "", "");

                if (!Page.ClientScript.IsClientScriptIncludeRegistered("JQuery"))
                {
                    Page.ClientScript.RegisterClientScriptInclude("JQuery", Page.ResolveUrl("~/Scripts/jquery-1.9.0.js"));
                }

                if (!Page.ClientScript.IsClientScriptIncludeRegistered("Default"))
                {
                    Page.ClientScript.RegisterClientScriptInclude("Default", Page.ResolveUrl("~/Default.js"));
                }

                script = "var _Default = new Default('" + this.ClientID + "','" + UniqueID + "',['_Default','']);";

                //Create the clientscript instance here.
                if (!Page.ClientScript.IsStartupScriptRegistered("_Default_Script"))
                {
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "_Default_Script", script, true);
                }
            }
        }

Why Page_Init event handle, not Page_Load or Page_PreRender. This is because Page_Init raised after all controls have been initialized … For detail, you can refer to ASP.NET Page Life Cycle Overview. When implement with web user controls, sometimes, I need methods in web user controls to be ready for consume when Page ready but never in the other way around.

I still need to include Page.ClientScript.GetCallbackEventReference method. Otherwise, the required resources(javascript) will not include to the page.

script = "var _Default = new Default('" + this.ClientID + "','" + UniqueID + "',['_Default','']);";

Default in this script is my javascript class for this page. It need 3 arguments during initialize. They are:

  • this.ClientID : this argument doesn’t make sense for this page because it doesn’t implement Master Page and not Web User Control. I have another page(Default.aspx in MasterPage folder) in the attached source code which need this argument value to register the event handler for each controls at client side.
  • UniqueID : as I mentioned, I need this argument value for WebForm_DoCallback method.
  • ‘_Default’ : my practice but not using in this sample. You can ignore it.

//cid = ClientID
//uid = UniqueID
//arg =  ClientInstanceName, "".
function Default(cid, uid, arg) {
    var that = this;

    this._uID = uid;
    this._cID = cid;
    this._clientInstanceName = arg[0];

    Default.prototype.GetData = function () {
        var data = new Array();

        data[0] = $("#FirstName")[0].value.toString();
        data[1] = $("#LastName")[0].value.toString();

        return data;
    };

    Default.prototype.UpdateData = function () {
        var arg = new String();

        arg = "UPDATE|" + this.GetData().join("|");

        WebForm_DoCallback(this._uID, arg, this.CallbackResult, null, null, true);
    };

    Default.prototype.CallbackResult = function (arg, context) {
        var data = arg.split("|");

        switch (data[0]) {
            case "UPDATE":
                alert("Callback done!");
                break;

            case "ERROR":
                alert(data[1]);
                break;
        }
    };

    Default.prototype.AddHandler = function () {
        var that = this;

        $("#SubmitButton_Callback").bind("click", function (s, e) {
            that.UpdateData();
        });
    };

    that.AddHandler();
}

Let’s have a look at Default.js file. If you going to ask about this and that, please spend some time on my previous blog post, This and That, and Javascript. Smile

Basically, I register an event handler for submit button click event. So it will execute UpdateData method, to get data and then execute Callback(WebForm_DoCallback) method. After the request travel to server and return, it will go the CallbackResult method. This has been registered at the WebForm_DoCallback method.

image

Now look at code behind, when I set a break point in RaiseCallbackEvent handler. I can see what had been passed from Callback method. With this, I can easily code and process these data and update to database. After this handler, the process will goes to GetCallbackResult handler. At this method, I code to check whether need to return result or error message. So that, at client side, I can handle it at CallbackResult method.

So, as you can see. To use Callback at ASP.NET, you have to code more. But it worth to do it if you wish to have a better server performance and a more responsive web site. It also make you have more understanding on ASP.NET.

Download Attachment


Leave a comment