.net泛型在序列化、反序列化JSON数据中的应用
在EXTJS使用过程中,起初都会被繁琐的JavaScript弄晕,或许你会抱怨这种开发把你带入了JavaScript海洋、或许你会为之而放弃项目的RIA技术。但是当你仔细研究JS控件的配置、数据绑定后,并会发现在服务端组织好JSON数据才是Ajax开发的重点、控件配置仅仅因为暂时没有可视化工具支持而造成的遗憾。
即使你放弃了ExtJS开发包,但是希望你不要放弃JSON、不要放弃Ajax、更不要放弃RIA开发。没有JSON时,你的页面传递数据受到限制,因为你不能传递复杂对象。JSON能够组织复杂的数据对象,访问复杂对象的成员和C#一样的方便,也正因为如此,JS控件才会诞生,我就是这么认为js控件因为有JSON的支撑才发展起来的。
首先分析一下Grid控件数据配置要求如下信息:
方式一:
[{"Field1":"","Field2","","Field3":""},
{"Field1":"","Field2","","Field3":""},
...
{"Field1":"","Field2","","Field3":""}]
方式二:
{totalCount:100, success:true, error:"" data:[{},{},...,{}]}
其中Fieldi可能不是简单数据结构而是个封装的对象。
这就需要我们AJAX服务端能够提供这样的JSON格式数据,这样的数据格式与WebService使用的xml格式数据是一致的,但是这里需要我们自己生成,这也就比WebService自动解析要灵活。
用JSONHelper对DataTable进行序列化:
/// <summary> /// 获取待办流程 /// </summary> public string GetFlowWait(int start, int limit, int userID) { string DGFolwWaitJSON = ""; JSONHelper json = new JSONHelper(); try { DataSet ds = biz.GetFlowWait(userID); json.success = true; if (start < ds.Tables[0].Rows.Count) for (int i = start; i < limit+start && i < ds.Tables[0].Rows.Count; i++) { DataRow dr = ds.Tables[0].Rows[i]; json.AddItem("id", dr["ID"].ToString()); json.AddItem("name", dr["Name"].ToString()); json.AddItem("creatorname", dr["CreatorName"].ToString()); json.AddItem("creatordept", dr["CreatorDept"].ToString()); json.AddItem("createdate", dr["CreateDate"].ToString()); json.AddItem("formcontent", dr["TemplateName"].ToString());//FormContent json.AddItem("templatename", dr["TemplateName"].ToString()); json.AddItem("currentstepid", dr["CurrentStepID"].ToString()); json.ItemOk(); } json.totlalCount = ds.Tables[0].Rows.Count; DGFolwWaitJSON = json.ToString(); } catch (Exception) { throw; } return DGFolwWaitJSON; }
这种序列化的方法很麻烦,而且只能对简单数据类型进行序列化。如果对象成员自身也是复杂对象(如List<T>)的话,上述方法就无能为力了。服务器如何组织这样的复杂JSON对象呢?
Newtonsoft.Json.dll与System.Web.Script.Serialization都有序列化、反序列化JSON数据的功能。
原型如下:
System.Web.Script.Serialization.JavaScriptSerializer js = new JavaScriptSerializer(); string strJSON= js.Serialize(object); T t=js.Deserialize<T>(string); string strJSON= Newtonsoft.Json.JavaScriptConvert.SerializeObject(object); T t= Newtonsoft.Json.JavaScriptConvert.DeserializeObject<T>(string);
public class JSONObject<T> { private bool _success; /// <summary> /// 是否成功 /// </summary> public bool success { get { return _success; } set { _success = value; } } private T _Object; /// <summary> /// 业务实体对象 /// </summary> public T Object { get { return _Object; } set { _Object = value; } } private string _msg; /// <summary> /// 消息 /// </summary> public string msg { get { return _msg; } set { _msg = value; } } }
接下来,业务实体类定义:
【调拨单MoveInfo -》调拨设备明细MoveDetailInfo】 ,典型的一对多关系。
/// <summary> /// /// MoveInfo 调拨单 /// </summary> public class MoveInfo { #region 属性 private int _ID; /// <summary>ID序号</summary> public int ID { get { return _ID; } set { _ID = value; } } private string _MoveID; /// <summary>MoveID 调拨单编号</summary> public string MoveID { get { return _MoveID; } set { _MoveID = value; } } private DateTime _MoveDate; /// <summary>MoveDate 调拨日期</summary> public DateTime MoveDate { get { return _MoveDate; } set { _MoveDate = value; } } private int _EX_Unit; /// <summary>EX_Unit 调出单位</summary> public int EX_Unit { get { return _EX_Unit; } set { _EX_Unit = value; } } private int _In_Unit; // <summary>In_Unit 调入单位</summary> public int In_Unit { get { return _In_Unit; } set { _In_Unit = value; } } private List<MoveDetailInfo> _Detail; /// <summary> /// /// 调拨设备明细信息 /// </summary> public List<MoveDetailInfo> Detail { get { return _Detail; } set { _Detail = value; } } #endregion 58 } /// <summary> 62 /// 调拨明细信息 63 /// </summary> public class MoveDetailInfo { #region 属性 private int _ID; /// <summary>ID序号</summary> public int ID { get { return _ID; } set { _ID = value; } } private string _M_ID; /// <summary> M_ID 调拨单ID</summary> public string M_ID { get { return _M_ID; } set { _M_ID = value; } } private string _DVID; /// <summary> DVID 资产编号</summary> 86 public string DVID { get { return _DVID; } set { _DVID = value; } } private string _DVName; /// <summary> DVName 设备名称</summary> public string DVName { get { return _DVName; } set { _DVName = value; } } private string _DVType; /// <summary> DVType设备型号</summary> public string DVType { get { return _DVType; } set { _DVType = value; } } #endregion 108 }
1. 服务端序列化
得到的JSON如下:
2. 客户端反序列化
ExtJS处理: Ext.Ajax.request接收服务端传来的数据后,客户端JS即可使用JSON数据了。
3.服务端反序列化
【继】 .Net FrameWork3.0之后就提供了JSON、XML数据的序列化、反序列化支持,同时支持JSON和XML之间的映射。 相见WCF介绍http://msdn.microsoft.com/zh-cn/library/bb412170.aspx 。