Friday, January 21, 2011

ASP.NET and asynchronous communication

Today I had to add a delete function to an old ASP.NET WebForms website. It was missing because there are a lot of relational data. So the steps to delete a record are:
- Click delete button
- Proof of existing relational data
- Show the result to the customer (and ask what to do)
- Delete all or cancel the delete action

Because I'm used to work with ASP.NET MVC, I thought on jQuery to solve the problem. Async calls to an Action on a Controller class and showing the result in a modal popup are easy tasks to do in ASP.NET MVC. This because of the MVC architecture, specially the Routing Engine used in MVC.
But in this case, I had to deal with ASP.NET WebForms and no routing to a Controller class. So how to solve the problem? I saw four different ways to do it:
1) Build a WCF Service and call it with jQuery
2) Create a ashx handler and call it with jQuery
3) Set the [WebMethod] Attribute to a method in the aspx page and call it with jQuery
4) Use the ScriptManager, the [WebMethod] and [ScriptMethod] Attribute


The first option (1), building a WCF Service is to much work for this small task.


The secound option (2) is quite good. The only thing I don't like is, I have to deal with two files what makes maintainance harder. Let's take a look at this solution anyway.
The jQuery code to call the handler looks like:

$(document).ready(function () {
$("#deleteButton").click(function () {
$.ajax({
type: "POST",
url: "Handler1.ashx",
data: "{'siteId':'" + id + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// What you like to do on success
},
fail: function (msg) {
// What you like to do on error
}
});
});
});

The Handler (ashx-File) can be added easily with Visual Studio. Just select the Generic Handler template. The code looks like:

public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// Check for relational data and generate the message
var message = "Generated message for the user";

context.Response.ContentType = "text/plain";
context.Response.Write(message);
}
...
}


The third option (3) is in this case my favorite. Simple and easy. The jQuery call is the same, just the URL changes to something like
...
url: "SiteName.aspx/IsDeletable",
...
where the parameter after the slash is the name of the method.
In the ASPX-File we have to add a static method and decorate it with the [WebMethod] attribute. That's it! The code looks like:

[WebMethod]
public static string IsDeletable(Guid siteId)
{
// Check for relational data and generate the message
var message = "Generated message for the user";
return message;
}

IMPORTANT: The method has to be static.


The last option is ASP.NET WebForms specific and uses the ScriptManager. In my opinion do we have a better solution with the jQuery version. Anyway, here is what you need:

Add a ScriptManager as follow:
... ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" ...

Add JavaScript code to make the call:
...
PageMethods.IsDeletable(id);
...
Notice that this is just the call. Get and handle the return value has to be added as well.

And on the method in our aspx-File we do need an additional attribute:
[System.Web.Script.Services.ScriptMethod()]


Now it's up to you to choose your right solution.

No comments: