打通.NET 3.5與ExtJS數據交互的任督二脈
ExtJS是一套非常好的UI框架,已經有越來越多的企業級應用程序使用上了這個框架而從中受益。然后,在眾多的項目當中,以J2EE項目居多,原因是ExtJS與Java的集成化越來越強。而對于使用.NET平臺的開發者來說,想要在自己的項目當中使用ExtJS卻困難重重,原因在于數據通信很難達到統一。在.NET 3.5以前,.NET平臺提供有限的JSON原生支持。因而很多程序員都是使用第三方的組件。例如LitJson.net組件。
在.NET 3.5中,框架提供了DataContractJsonSerializer類,可以方便地對對象進行JSON序列化跟反序列化。另外,.NET3.5提供了擴展方法跟LINQ,更是對我們的開發如虎添翼。在這篇BLOG中,我將使用這些新特性,對如何把ExtJS與.NET通信進行集成進行了分析。有什么錯誤,請大家指正,歡迎交流。
一、使用DataContractJsonSerializer類
該類用于對對象進行JSON序列化跟反序列化。該類位于System.Runtime.Serialization.Json命名空間中。是.NET3.5平臺新增的類。主要使用WriteObject()跟ReadObject()方法對對象進行相應的操作。相關的API,可參考MSDN。
二、擴展方法
擴展方法,是.NET 3.5提供的新特性,用于增強原生對象的功能支持,擴展對象的功能。相關的介紹,請參照MSDN或相關書籍。
三、泛型
泛型對于許多.NET的程序員并不陌生。在.NET 2.0之后,已經在框架中添加了對泛型的支持。泛型使到我們減少了對象在裝箱跟拆箱的過程中資源的損耗。
接下來,我們可以編寫如下的代碼,用以擴展類的JSON序列化功能。我使用了擴展方法,并且使用泛型約束,約束了類型必須為類。
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;
using System.Runtime.Serialization.Json;
///
/// Summary description for JsonExtends
///
public static class JsonExtends
{
public static string ToJson<T>(this T obj) where T: class
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType
());
string output = string.Empty;
using (MemoryStream ms = new MemoryStream())
{
ser.WriteObject(ms, obj);
StringBuilder sb = new StringBuilder();
sb.Append(Encoding.UTF8.GetString(ms.ToArray()));
output = sb.ToString();
}
return output;
}
public static T FromJson<T>(this string jsonString) where T : class
{
T ouput = null;
try
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T
));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes
(jsonString)))
{
ouput = (T)ser.ReadObject(ms);
}
}
catch (Exception) { }
return ouput;
}
}
建立實體類,注意:為了序列化類及類成員,必須是類成員上使用DataContract屬性,成員則需要使用DataMember屬性,忽略DataMember屬性的成員將不被序列化。同時,DataMember屬性也適合集合成員,其序列化的結果將是一個jSON數組。
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
///
/// Summary description for Employee
///
[DataContract]
public class Employee
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
//public List Payments { get; set; }
}
建立一般處理程序EmployeesPayment.ashx,用以向ExtJS交互數據的接口。用ashx而不用aspx的好處,是ashx不用經歷復雜的頁面生命周期,效率大大提高。
using System.Web;
using System.Collections.Generic;
public class EmployeesPayment : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "application/x-json";
Employee employee = new Employee { LastName = "光年", FirstName = "巴斯" };
context.Response.Write(employee.ToJson<Employee>());
}
public bool IsReusable {
get {
return false;
}
}
}
JSON表現層
Ext.onReady(function() {
var fr = new Ext.FormPanel({
title: '測試JSON',
frame: true,
id: 'frJson',
autoHeight: true,
applyTo: 'con',
width: 200,
labelWidth: 30,
items: [
new Ext.form.TextField({
fieldLabel: '名',
id: 'FirstName'
}),
new Ext.form.TextField({
fieldLabel: '姓',
id: 'LastName'
})
],
buttons: [
{
text: '提取數據',
handler: function() {
Ext.MessageBox.wait('正在加載數據', '加載數據');
var config = {
url: 'EmployeesPayment.ashx',
method: 'GET',
success: function(res, op) {
Ext.MessageBox.hide();
var obj = Ext.decode(res.responseText);
Ext.getCmp('FirstName').setValue(obj.FirstName);
Ext.getCmp('LastName').setValue(obj.LastName);
}
};
Ext.Ajax.request(config);
}
}
]
});
});