Introduction
This article will discribe how to take a server side object, provide it to the client using JSON serialization and then return it back to the server.
Background
The AJAX javascript framework in the article builds upon other javascript frameworks I have developed. The following frameworks also need to be included in the the client page.
Using the code
There a several components required to complete the cycle from server to client to server. These are:
- Data Object
- AJAX Get Page
- Web Page
- AJAX Post Page
Data Object
The following is the data object. Javascript serialization uses WCF technology so we need to treat the object like any WCF contract. The DataContract and DataMember attributes describe how the object is to be serialized.
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace DataModel
{
[DataContract]
public class CodeModel
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Description { get; set; }
}
}
AJAX Get Page
The following page renders the data object in a JSON format. This is requested through the AJAX framework and returned to the client as a javascript object. With this page the server side code overrides the response so no content is required for the ASPX page. The following is the server side code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DataModel
{
public partial class JSON : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();
CodeModel cm = new CodeModel();
cm.Code = "TEST";
cm.Description = "Test Value";
string json = jss.Serialize(cm);
Response.Write(json);
Response.End();
}
}
}
Web Page
This is the page the contains the AJAX framework. I wont show the whole page contents but just the framework and how to implement it. The following code is the framework.
var doingAJAX = false;
var AJAXPostValue = function(name, value) {
this.Name = name;
this.Value = value;
}
var AJAXRequestManager = function() {
this.OnReturn = new uiEvent();
this.OnError = new uiEvent();
this.Reset = function() { this.OnReturn = new uiEvent(); this.OnError = new uiEvent(); }
this.Send = function(URL, postValues) {
if (doingAJAX) {
setTimeout('AJAXRM.Send(\'' + URL + '\');', 100);
return;
}
doingAJAX = true;
var xmlHttpReq = false;
var self = document;
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', URL, true);
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
var obj = null;
try {
obj = eval('(' + self.xmlHttpReq.responseText + ')');
AJAXRM.OnReturn.Fire(obj);
}
}
catch (ex) {
AJAXRM.OnError.Fire(({ "IsError": true, "Message": escape('JSON Serialisation Error'), "Stack": 'Javascript' }));
}
doingAJAX = false;
}
}
var postValue = null;
if(postValues != null) {
postValue = '';
for (var x = 0; x < postValues.length; x++)
postValue += postValues[x].Name + '=' + escape(this.Serialize(postValues[x].Value)) + (x == postValues.length - 1 ? '' : '&');
}
self.xmlHttpReq.send(postValue);
}
this.Serialize = function(obj) {
var isArray = obj.constructor.toString().indexOf('Array') > -1;
var serial = isArray ? '[' : '{';
for (var a in obj) {
if (typeof obj[a] != 'function') {
serial += isArray ? '' : a + ':';
if (typeof obj[a] == 'object')
serial += this.Serialize(obj[a]);
else if (typeof obj[a] == 'string')
serial += '\'' + obj[a] + '\'';
else
serial += obj[a];
serial += ',';
}
}
serial = serial.substring(0, serial.length - 1);
serial += isArray ? ']' : '}';
return serial;
}
}
var AJAXRM = new AJAXRequestManager();
The following javascript code creates the AJAX object and gets the code object from the server. Changes its values and returns it back to the server.
AJAXRM is the framework object. The Reset method clears the event bindings for OnError and OnReturn. The send method receives the URL and the post value array.
The post value array is a standard Array object containing instances on the AJAXPostValue object. The AJAXPostValue object receives two values when constructed. Name: the id to be posted. Value: the object to be posted.
AJAXRM.Reset();
var OnSuccess = function(obj) {
ReturnObject(obj);
}
var OnError = function(ex) { alert(ex.Message); }
AJAXRM.OnError.Register(OnError);
AJAXRM.OnReturn.Register(OnSuccess);
AJAXRM.Send('JSON.aspx', null);
function ReturnObject(obj) {
obj.Code = 'TEST2';
obj.Description = 'New Description';
var OnPostSuccess = function(obj) { alert('sent'); }
AJAXRM.Reset();
AJAXRM.OnError.Register(OnError);
AJAXRM.OnSuccess.Register(OnPostSuccess);
var PostValues = new Array();
var postObj = new AJAXPostValue('code', obj);
AJAXRM.Send('JSONPost.aspx', postObj);
}
AJAX Post Page
The following is the page the will receive the object back at the server. This call can also return a value but in this instance it will return 'null' as a string. Again there is no requirement for ASPX content. The following is the server side code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DataModel
{
public partial class JSONPost : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string json = Request.Form["code"];
System.Web.Script.Serialization.JavaScriptSerializer jss = new System Web.Script.Serialization.JavaScriptSerializer();
CodeModel cm = (CodeModel)jss.Deserialize<CodeModel>(json);
Response.Write("null");
Response.End();
}
}
}
Points of Interest
This also works with generics for requesting lists. You could therefore return type List<CodeModel> in the JSON page and it would deserialize by back to the generic list in the JSONPost page.