Calling the Server-Side Method Asynchronously From Client Script

Client Callbacks

Client Callbacks is a new feature of ASP.NET 2 that allows the client-side script to call the server-side method asynchronously without posting back to fetch new data from the server and change the display in the client browser dynamically.

Developers use JavaScript mainly to make the page more interactive and to avoid page postback. But there are often situations where posting the back of the page is necessary to fetch new data from the server/database. Consider a scenario where we have a dropdown list of Countries and a list box of the cities. The list box cities should display the cities based on the selected country from the dropdown list.

client callbacks

Now, in this case, we have to post back the page when the Country dropdown item is changed and fill the Cities listbox with the new items fetched from the database based on the Country selected. The simple way to avoid postback is to use Client Callbacks, where the JavaScript code will communicate with the server and refresh the Cities listbox without a postback.

The following procedure has to be followed to create Client Callbacks.

Step 1. To receive the call back from the client, the page must implement the ICallbackEventHandler interface.

public partial class ClientCallbackPage : System.Web.UI.Page, ICallbackEventHandler
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Page initialization code
    }

    public void RaiseCallbackEvent(string eventArgument)
    {
        // Handle the callback event, process the eventArgument
    }

    public string GetCallbackResult()
    {
        // Return the result to the client
        return "Callback Result";
    }
}

Step 2. The ICallbackEventHandler has two methods RaiseCallBackEvent(), which receives data from the client browser as a string argument and is triggered first, and GetCallbackResult(), which provides the data to the client browser and is triggered next.

In our example, we will pass the Selected Country value to the server in the RaiseCallBackEvent().

public void RaiseCallbackEvent(string callbackEventArgument)
{
    m_callbackEventArgument = callbackEventArgument;
}

m_callbackEventArgument is a private string member variable, and we will assign the selected country value passed from the client browser on it. Now in the GetCallbackResult() method, we can retrieve the cities list for the selected country from the database or any other datastore and passed the cities list back to the client browser. Here in this example, I have just hardcoded the cities list that is supposed to come from the database.

public string GetCallbackResult()
{
    string callbackResult = String.Empty;

    if (m_callbackEventArgument.Equals("India"))
    {
        callbackResult += "New Delhi|New Delhi;Mumbai|Mumbai;Kolkata|Kolkata;";
    }

    if (m_callbackEventArgument.Equals("China"))
    {
        callbackResult += "Beijing|Beijing;Shanghai|Shanghai;Xian|Xian;";
    }

    return callbackResult;
}

The main limitation of ASP.NET Client Callback is that you can send data to the client only as a single string. So, we are sending the cities to list to the client browser as a string separated by the ";" character and "|" character to separate the text and value field of the city. If you have to pass complex data, such as your collection of business object data, then you need to design a way to serialize the data into a string and deserialize the string on the client browser with JavaScript. One way is to have a XML string and pass it, and on the client side, it can be parsed with JavaScript either with the built-in XML parser or your own.

Step 3. The third step is to write a client script that will receive the data from the server and deserialize it and display it on the browser. We can give any name to the JavaScript method which handles the callback response from the server but should have two arguments.

function ClientCallbackScript(result, context) {
  var lstCity = document.forms[0].elements['lstCity'];
  lstCity.innerHTML = "";
  var cities = result.split(';');
  for (var i = 0; i < cities.length - 1; ++i) {
    var properties = cities[i].split('|');
    var cityName = properties[0];
    var cityId = properties[1];
    var option = document.createElement("option");
    option.value = cityId;
    option.innerHTML = cityName;
    lstCity.appendChild(option);
  }
}

Here the result parameter holds the data that is sent by the server, and now this has to be parsed and filled up in the cities list box.

Step 4. Now the final step is to define the event in which the Callback trigger is fired. Here in our case, we will define the Callback trigger to fire on the Country dropdown list changed event.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        FillCountryList();
        FillCityList(ddlCountry.SelectedValue);
        string callbackEventReference =
            Page.ClientScript.GetCallbackEventReference(
                this,
                "document.all['ddlCountry'].value",
                "ClientCallbackScript",
                "null"
            );

        ddlCountry.Attributes["onclick"] = callbackEventReference;
    }
}

The Page.ClientScript.GetCallbackEventReference returns a JavaScript code that calls the Client Callback. The first argument it takes is the ICallBackEventHandler object that will handle the callback, that is the page itself in our case. The second argument is the data that the client browser will pass to the server, i.e, the selected Country from the dropdown list. The third argument is the name of the JavaScript method that will receive the data from the server callback. And the last argument is the Context information that we want to pass. Here we are passing null.

Below is the complete sequence diagram of the above process.

preview


Similar Articles