If you are about to start using AJAX in your ASP.net application, you will be pointed to some existing frameworks, like: ASP.net AJAX, Anthem.net or something else. That is a probably a good idea to use time-proven things, but you also might have a reasons not do that. First of all, if you are new to AJAX and you need to educate yourself with it, using frameworks in not good, because it hides a lot of details of “how it works”. Second reason, that you might not want to overhead with additional frameworks, to make it as lightweight as possible. If you are about to implement some simple AJAX operations, then jQuery for client code, Json.net to handle JSON on server side and ASP.net HttpHandler is all that you need!
Let’s briefly review each of these components:
-
jQuery - everybody knows jQuery, it is the best javascript framework, created by John Resig.
-
Json.net - just create and easy to use framework of serialize/deserialize .net objects to JSON, created by James Newton-King.
-
Generic Handlers - part of ASP.net framework. With some level of simplicity HttpHanlers could be called a page without any overhead (like a Page with no HTML code and only Page_Load method), that is ideally serves as a handler for AJAX calls.
Preparation
We going to create a simple admin page that could: get list of all users
registered in system and quick new user. I'll use the same project that I used
in my previous web development articles, called Concept, so as always you could
get a source code on github.
Generic Handler implementation
I web project I’ve added new folder, called handlers that would contain all handlers code we wish to have. Add new
"Generic Handker" item into this folder, and call it users.ashx.
The skeleton code of handler will look like that:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Company.Product.DAL;
using Company.Product.BLL;
namespace WebApplication.handlers
{
/// <summary>
/// Summary description for users
/// </summary>
public class users : IHttpHandler
{
private UsersOperations _operations = new UsersOperations(new UsersRepository());
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
var respose = string.Empty;
var function = context.Request["function"];
switch (function)
{
case "list":
respose = CreateListReponse(context);
break;
case "add":
respose = CreateAddUserResponse(context);
break;
}
context.Response.Write(respose);
}
private string CreateAddUserResponse(HttpContext context)
{
return _operations.InsertUser(context.Request["Email"], context.Request["SecretPhrase"], context.Request["Password"]);
}
private string CreateListReponse(HttpContext context)
{
return _operations.GetAllUsers();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
* This source code was highlighted with Source Code Highlighter.
Two important thing here: first, we declare context.Response.ContentType = “application/json”; meaning that body response will contain json code.
Second, request will contain a function parameter, that would contain exact function
name we want to call. It our case it will be just 2 functions, list and add.
Serialization of data
Json.net made a serialization of .NET objects to Json very easy. It supports all main types and collections, it also extendable for your custom needs. Code that returns the list of all users:
namespace Company.Product.BLL
{
public class UsersOperations
{
private IUsersRepository _data;
public UsersOperations(IUsersRepository data)
{
_data = data;
}
public string GetAllUsers()
{
return JsonConvert.SerializeObject(new { status = "success", data = _data.GetAll() });
}
public string InsertUser(string email, string secret, string password)
{
var user = new User { Email = email, SecretPhrase = secret, Password = password };
_data.InsertUser(user);
return JsonConvert.SerializeObject(new { status = "success", data = user.Id });
}
}
}
* This source code was highlighted with Source Code Highlighter.
Users repository GetAll() method returns IEnumerable of User. JsonConvert understands such data types, so able to perform serialization not problem.
Aspx code
In aspx I utilize functionality of $.ajax call, as well as very nice component called blockUI, that works upon jQuery and helping to block interaction during AJAX calls, as well as creation of simple modal dialogs.
<%@ Page Title="" Language="C#" MasterPageFile="~/Concept.Master" AutoEventWireup="true"
CodeBehind="UserOperations.aspx.cs" Inherits="WebApplication.UserOperationsView" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
function listOfUsers() {
$.ajax(
{
url: "/handlers/users.ashx?function=list",
beforeSend: function () {
$("#results").slideUp();
$.blockUI();
},
cache: false,
success: function (response) {
$.unblockUI();
if (response.status == "success") {
listOfUserCallback(response);
}
}
});
return false;
}
function listOfUserCallback(response) {
var html = "<ul>";
for (var key in response.data) {
html += "<li>" + response.data[key].Id + ": " + response.data[key].Email + "</li>";
}
html += "</ul>";
$("#results").html(html);
$("#results").slideDown();
}
function showDialog() {
$.blockUI({ message: $("#adduserdialog") });
return false;
}
function closeDialog() {
$.unblockUI();
}
function addUser() {
var user = {};
user.Email = $("input#email").val();
user.Password = $("input#password").val();
user.SecretPhrase = $("input#phrase").val();
$.ajax(
{
url: "/handlers/users.ashx?function=add",
beforeSend: function () {
$.blockUI({ message: "<h1>Adding new user, please wait...</h1>" });
},
data: user,
success: function (response) {
$.unblockUI();
if (response.status == "success") {
addUserCallback(response);
}
}
});
return false;
}
function addUserCallback(response) {
//renew list of user:
listOfUsers();
}
$().ready(function () {
$("#results").hide();
//setup handlers
$("a#list").click(listOfUsers);
$("a#add").click(showDialog);
//setup dialog
$("input#adduser").click(addUser);
$("input#cancel").click(closeDialog);
}
);
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div id="content">
<div id="adduserdialog" style="display: none; cursor: default">
<label>
Email:</label>
<input id="email" type="text" />
<label>
Secret phrase:</label>
<input id="phrase" type="text" />
<label>
Password:</label>
<input id="password" type="password" />
<input type="button" id="adduser" value="Add user" />
<input type="button" id="cancel" value="Cancel" />
</div>
<div id="left">
<div id="box">
<p>
Admin operations:
</p>
<a id="list" href="#">List of users</a><br />
<a id="add" href="#">Add new user</a>
</div>
</div>
<div id="right">
<div id="results">
</div>
</div>
</div>
</asp:Content>
* This source code was highlighted with Source Code Highlighter.
Putting all together
Now let’s review everything in conjuction. We have generic handler, that receives http request. It uses request “function” to understand what function is requested by user. Based on function type it delegates the call to business object, called UsersOperations. UserOperations relies on UserRepository to work with data, so it get or insert the data and return results as JSON strings. JSON is created by serialization of .NET objects into JSON objects by means of Json.net library. Client receives the output in asynchronous callbacks, checks the status of operation and dynamically creates HTML code. blockUI component help to block user interaction with UI during asynchronous calls, also “create new user” modal dialog is created by means of blockUI.
Such approach serves really great for simple AJAX applications, on pure ASP.net, jQuery. Check out sources on Github.