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

ASP.NET Callback – and HOW?

0.00/5 (No votes)
28 Jan 2013CPOL3 min read 23.1K  
Implementing ASP.NET callback.

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

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

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

Since things became clear to me, I planned to write everything in JavaScript file. I quickly check what is WebForm_DoCallback and what are the arguments that it demands.

JavaScript
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 & a lot of testing, I can confirm it is UniqueID of the page/web user control. So it ends up with this code in my page.

C#
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 details, you can refer to ASP.NET Page Life Cycle Overview. When implementing with web user controls, sometimes, I need methods in web user controls to be ready for consumption when Page is ready but never the other way around.

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

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

Default in this script is my JavaScript class for this page. It needs 3 arguments during initialization. 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 the MasterPage folder) in the attached source code which needs this argument value to register the event handler for each control on the 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.
JavaScript
//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 the 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 go to GetCallbackResult handler. In this method, I code to check whether I need to return result or error message. So that, at client side, I can handle it in the CallbackResult method.

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

License

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