Wednesday, January 30, 2008

Mind your callbacks

These days I'm using quite a lot of Callbacks, that is requests to the server that don't refresh the entire page, but only a specific section, creating the illusion of a snappier user interface. As such, they are becoming a necessity in these days of Users 2.0 (ie users who have gotten used to Web 2.0 functionalities, much as I loathe the term).

Google were one of the main early adopters of callbacks, but now everyone is doing it, and so are the main out-of-the-box software vendors such as Telerik or ComponentArt. These days the challenge would be to find a grid that does not implement the latest AJAX-style gadgets.

Our 3rd party vendor of choice is currently ComponentArt, and I've been using their Callback mechanisms quite extensively lately. They're quite good, although sometimes its still necessary to go down to the nitty-gritty of client-side scripting, which is not for the faint of hearted.

Of course, while callbacks are great, they tend to have a big impact on they way your applications are constructed, amongst others interfering with what we consider "best practices", such as:

* Strong Typing (hello Mr JavaScript)
* Error Handling (an alert window does not make an error handler)
* Intellisense (maybe not a best practice, but damn handy to have anyway)

Anyway, in the end its just (yet) another technology paradigma shift and most of those "best practice" challenges can be solved decently enough, given a little time and effort. Lets take error handling as an example:

Problem: When an error occurs during a Callback, the typical error message is "Data cannot be loaded", delivered in the form of a javascript alert. Not too useful, not to mention the fact that your page is potentially left in a compromised state.

Solution: In the end, the Callback method is just another server-side method, so encapsulate it in an try/catch block and provide adequate error handling. After that, generate some client-side script to redirect the user away from the page to some nice error page.

protected void MyCallBack(object sender, CallBackEventArgs e)
{
try
{
BindGrid();
panel.RenderControl(e.Output);
}
catch(Exception ex)
{

new ErrorReporter().HandleError(Request, ex);
CallBackErrorHandler.RedirectToErrorPage("Error.aspx", panel, e.Output);
}
}


and then in our CallBackErrorHandler class:

public static class CallBackErrorHandler
{
public static void RedirectToErrorPage(string redirectUrl, Control container, HtmlTextWriter output)
{
string str = "<script type='text/javascript'>";
str += "window.location = '" + redirectUrl + "'</script>";
Literal lit = new Literal();
lit.Text = str;
container.Controls.Add(lit);
container.RenderControl(output);
}
}


Old tricks, new techology :)

No comments: