Implementing AJAX in ASP.NET

Miscellaneous

Registering functions in another class

In the above example, our server-side functions resided within the code behind of the executing page. However, there’s no reason why these functions can’t be in a separate class file. Remember, the way the wrapper works is to find all methods within the specified class that have the Ajax.AjaxMethod. The class in question is specified via the second script tag. Using Ajax.Utility.RegisterTypeForAjax we can specify any class we want. For example, it would be reasonable to keep our server-side functions in a separate class:

Public Class AjaxFunctions
  <Ajax.AjaxMethod()> _
  Public Function Validate(username As String, password As String) As Boolean
    'do something
    'Return something
  End Function
End Class

We could have the Ajax wrapper create proxies for this class by specifying this class’s type instead of the pages:

VB.NET

Private Sub Page_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  Ajax.Utility.RegisterTypeForAjax(GetType(AjaxFunctions))
  '...
End Sub

C#

private void Page_Load(object sender, EventArgs e){
  Ajax.Utility.RegisterTypeForAjax(typeof(AjaxFunctions));
  //...
}

Remember, the client-side proxy takes the name of <ClassName>.<ServerSideFunctionName>. Therefore, if our ServerSideAdd function was located in the fictional AjaxFunctions class above, our client-side call would be: AjaxFunctions.ServerSideAdd(1,2)

How the proxy really works

The second script tag generated by the Ajax utility (or manually inserted by you) passes the namespace, class name and assembly of the page. Armed with this information, the Ajax.PageHandlerFactory is able to use reflection and get the details about any functions which have a certain attribute. Obviously, the handler looks for functions with the AjaxMethod attribute, gets their signature (return type, name, and parameters) and is thus able to create the necessary client-side proxy. Specifically, the wrapper creates a JavaScript object named the same name as your class which exposes the proxy. In other words, given a server-side class AjaxFunctions with an Ajax method ServerSideAdd, we should expect a JavaScript object named AjaxFunction which exposes a ServerSideAdd function. You can see this in action by pointing your browser to the path of the second script tag.

Returning Unicode characters

Ajax .NET wrapper is able to return Unicode characters from the server to the client. To do so, values must be html encoded on the server before being returned. For example:

[Ajax.AjaxMethod]
public string Test1(string name, string email, string comment){
  string html = "";
  html += "Hello " + name + "<br>";
  html += "Thank you for your comment <b>";
  html += System.Web.HttpUtility.HtmlEncode(comment);
  html += "</b>.";
  return html;
}

SessionState

It’s likely that you’ll need to access session information in your server side function. To do so, you must simply tell Ajax to enable such functionality via a parameter passed to the Ajax.AjaxMethod attribute.

While looking at the session capabilities of the wrapper, let’s look at a couple other features. In this example, we have a document management system which puts a lock on a document while a user is editing it. Other users can request to be notified when the document because available. Without AJAX, we’d need to wait until the user posted back in order to check if his or her queued documents were available. This is obviously not ideal. Using Ajax with session state support, this is quite easy.

First we’ll write our server side function, the goal of which is to loop through the documentIds the user wishes to edit (stored in a session) and return all released documents.

VB.NET

<Ajax.AjaxMethod(HttpSessionStateRequirement.Read)> _
Public Function DocumentReleased() As ArrayList
  If HttpContext.Current.Session("DocumentsWaiting") Is Nothing Then
    Return Nothing
  End If
  Dim readyDocuments As New ArrayList
  Dim documents() As Integer = CType(HttpContext.Current.Session("DocumentsWaiting"), Integer())
  For i As Integer = 0 To documents.Length - 1
    Dim document As Document = document.GetDocumentById(documents(i))
    If Not document Is Nothing AndAlso document.Status = DocumentStatus.Ready Then
      readyDocuments.Add(document)
    End If
  Next
  Return readyDocuments
End Function

C#

[Ajax.AjaxMethod(HttpSessionStateRequirement.Read)]
public ArrayList DocumentReleased(){
  if (HttpContext.Current.Session["DocumentsWaiting"] == null){
    return null;
  }
  ArrayList readyDocuments = new ArrayList();
  int[] documents = (int[])HttpContext.Current.Session["DocumentsWaiting"];
  for (int i = 0; i < documents.Length; ++i){
    Document document = Document.GetDocumentById(documents[i]);
    if (document != null && document.Status == DocumentStatus.Ready){
      readyDocuments.Add(document);
    }       
  }
  return readyDocuments;
  }
}

Notice that we specify the HttpSessionStateRequirement.Read value (alternatives being Write and ReadWrite).

Now we write our JavaScript to take advantage of this method:

<script language="javascript">
function DocumentsReady_CallBack(response){
  if (response.error != null){
    alert(response.error);
    return;
  }
  if (response.value != null && response.value.length > 0){
    var div = document.getElementById("status");
    div.innerHTML = "The following documents are ready!<br />";
    for (var i = 0; i < response.value.length; ++i){
      div.innerHTML += "<a href=\"edit.aspx?documentId=" + response.value[i].DocumentId + "\">" + response.value[i].Name + "</a><br />";
    }     
  }
  setTimeout('page.DocumentReleased(DocumentsReady_CallBack)', 10000);
}
</script> 
<body onload="setTimeout('Document.DocumentReleased(DocumentsReady_CallBack)', 10000);">

Our server side function is called once on page load and subsequently every 10 seconds. The call back function checks the response to see if any values were returned, and if so displays the newly available documents to the user in a div tag.

Conclusion

AJAX technology has already lead to sleek and rich web interfaces, previously reserved for desktop development. The Ajax .NET wrapper allows you to easily take advantage of this new power. Note that both the Ajax .NET wrapper and the documentation are under development.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“There are only 3 numbers of interest to a computer scientist: 1, 0 and infinity”