REST Services for JSON objects using ASP.NET AJAX

JSON does have it’s place in an AJAX architecture. It’s just a quick and dirty way to get javascript objects back from backend data sources. The nice thing about ASP.NET AJAX is that it can convert a Web Service endpoint to an AJAX friendly semi-REST endpoint that serves a JAvaScript serialized object. To do this, just mark the Web Service method with the following attribute:

[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]

The nice thing about this is that it only affects the script client. The script client is defined as a client that sends the http header "Content-Type" with the value "application/json; charset=utf-8". If you use the web service proxy, you don’t need to do anything. However, you don’t really get any benefits of hitting the service with the GET endpoint. The real benefits of converting to the REST/GET endpoint is in using client side caching with the last-modified header (another REAL cool topic I’ll cover soon), and you can’t access anything from the request when you use the cute little proxy. So to get the real benefits of the REST endpoint, use the Sys.Net.WebRequest class to make your own web request.

First, here’s the example web service endpoint:

//example.asmx:

[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public List<SomeClass> GetSampleData()
{
   List<SomeClass> stuff = new List<SomeClass>();
   stuff.Add(new SomeClass("meaning of life",42);

   // We’ll talk about last modified and caching in another post. For now…
   HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
   HttpContext.Current.Response.Cache.SetExpires(DateTime.Now – TimeSpan.FromDays(3600));

   return stuff;
}

Given that endpoint, here’s the JavaScript request for the endpoint. Note the Content-Type header I’ve bolded, this is key to accessing the endpoint. You’ll see that you can’t access the endpoint in normal IE, as the content type header is expected for the GET endpoint.  

var request = new Sys.Net.WebRequest();
//- note that the header is the magic key to the endpoint:
request.get_headers()[‘Content-Type’] = ‘application/json; charset=utf-8’;
var path = ‘example.asmx/GetSampleData’;
request.add_completed(onSampleComplete);
request.set_url(path);
request.invoke();

…and then the callback handler:

function onSampleComplete(response){
  // you could check the last modified here against the last version that you got,
  // and add some conditional processing. 
  // We’ll talk about lastModified and client caching in another post.
   var lastModified = response.getResponseHeader(‘Last-Modified’);

   var sampleData = response.get_object();
  // now do something with that sample data!
}

And there you have it! You now have a REST/GET endpoint implemented on the server that returns JSON objects, without coding any JSON transformations yourself. You’ve also got the normal ASMX/SOAP endpoint for .NET clients, without compromising your service layer.  Beautiful!

In another post soon we’ll talk about client data caching for AJAX applications using .NET server endpoints. With this method, you can pass the Last-Modified header back and forth (without client code) and check the server data to see if there’s new data.

Got feedback or questions? Let me know!

This entry was posted in Ajax. Bookmark the permalink.

Leave a Reply