Monday, November 27, 2006

Using WebHandlers with jQuery (ASP.NET 2)

A WebHandler is a useful way for updating data without needed to resort to an ASP.NET page (with its additional overhead). You can decide what content type to send (so can send data as text/html, text/plain or even image/jpeg - all can be handled with the same file) and don't have to worry about view state, but you cannot use the WYSIWYG utilities you may normally use so they are more suited to those comfortable with coding by hand. Combine this with jQuery and you have an easy way to update records (or do any kind of processing on the server) without using postbacks (and it can result in a more efficient application).

The ASP.NET page

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
 <title>Test Page</title>

 <script src="jquery-latest.pack.js" type="text/javascript"></script>

 <script type="text/javascript">
 $(
  function()
  {
   $("input[@name$=AddRecord][@type=submit]").click(addRecord);
  }
 )
 function addRecord()
 {
  var data = $("#addcontact input[@type=text], #addcontact textarea").serialize();
  var tmp = data.split("&");
  var tmp2 = [];
  var fielddata;
  for(var f in tmp)
  {
   // $'s are used to make unique names (eg ctl00$FirstName, ctl00$MyPanel$FirstName), so it is split
   fielddata = tmp[f].split("$");
   // deliminator in .NET 1.1 is ':' so tmp[f].split(":") should hopefully work
   // get the item in the array (which is the field name and data)
   tmp2[tmp2.length] = fielddata[fielddata.length - 1];
  }
  // set new data
  data = tmp2.join("&");
  $.ajax(
   {
    type: "POST",
    url: "addrecord.ashx",
    data: data,
    success: function(msg)
    {
     alert(msg);
    }
   }
  );
  return false;
 }
 </script>

</head>
<body>
 <form runat="server">
  <div id="addcontact">
   <p>
    First Name:
    <asp:TextBox ID="FirstName" runat="server"></asp:TextBox></p>
   <p>
    Last Name:
    <asp:TextBox ID="LastName" runat="server"></asp:TextBox></p>
   <p>
    Address:<br />
    <asp:TextBox ID="Address" runat="server" TextMode="MultiLine"></asp:TextBox>
   </p>
   <asp:Button ID="AddRecord" runat="server" Text="Add" />
  </div>
 </form>
</body>
</html>

The WebHandler

Simply create a blank text file with the extension ashx, e.g. addrecord.ashx in the same folder as you ASP.NET page (although it is named addrecord, it could be used to modify existing records, get an associated photo etc.

<%@ WebHandler Language="C#" Class="AddRecord" %>

using System;
using System.Collections.Specialized;
using System.Web;

public class AddRecord : IHttpHandler
{

 public void ProcessRequest(HttpContext ctx)
 {
  ctx.Response.ContentType = "text/plain";
  if (ctx.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
  {
   // get all form items
   NameValueCollection formItems = ctx.Request.Form;
   // loop through fields in the form
   foreach (string field in formItems)
   {
    ctx.Response.Write(field + " : " + formItems[field] + "\n");
   }
  }
  else
  {
   ctx.Response.Write("Access denied");
  }
 }

 public bool IsReusable
 {
  get
  {
   return false;
  }
 }

}

No comments: