记得一本杂志上说过,“程序员可以没有空气和水,但不能没有xml和可乐”,在那个年代,xml的确非常重要的,像唯一的宠儿,现在呢,很多东西除了可以保存成xml意外有时候也选择json,甚至在设计组件时除了提供xml的数据接口,也会提供JSON的数据接口了;web程序中可以用,silverlight程序中也提供了一些基础性支出;可见JSON的重要性了。有不少学生问我在.Net中JSON到底好用不好用?其实非常好用。
在客户端,有个json2.js文件提供的parse和stringify方法可以实现客户端对json对象的解析和包装,例如:
function btn_onclick() {
var obj = new Object();
obj.Name = "老杨";
obj.Title = "CIO";
var x = JSON.stringify(obj);//json2.js文件中提供的方法
$.post("ServerOrResource/TE.ashx", {"ob":x}, function (res) {
var hs = "姓名:" + res.Name + " 职务:" + res.Title; //可以直接通过属性名称来进行访问。
$("#divA").html(hs);
}, "json");
}
var obj = new Object();
obj.Name = "老杨";
obj.Title = "CIO";
var x = JSON.stringify(obj);//json2.js文件中提供的方法
$.post("ServerOrResource/TE.ashx", {"ob":x}, function (res) {
var hs = "姓名:" + res.Name + " 职务:" + res.Title; //可以直接通过属性名称来进行访问。
$("#divA").html(hs);
}, "json");
}
实际上,开始使用jquery后,parse方法已经很少使用了,只需要在最后指明 返回数据是 "json"即可。在服务端处理起来容易么?同样是非常容易的,在.net3.5之前,一般使用第三方组件,好像叫 Newtonsoft.Json什么的,在.net3.5 之后,可以封装一个类来进行处理,例如:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
/// <summary>
///JsonHelper 的摘要说明
/// </summary>
public class JsonHelper
{
public static string SerializeObject(Object obj)
{
string json = "";
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
ser.WriteObject(ms, obj);
json = System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
return json;
}
public static T DeSerializeObject<T>(string json)
{
System.Text.UTF8Encoding utf = new System.Text.UTF8Encoding();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
using (System.IO.MemoryStream s = new System.IO.MemoryStream(utf.GetBytes(json)))
{
return (T)ser.ReadObject(s);
}
}
}
///JsonHelper 的摘要说明
/// </summary>
public class JsonHelper
{
public static string SerializeObject(Object obj)
{
string json = "";
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
ser.WriteObject(ms, obj);
json = System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
return json;
}
public static T DeSerializeObject<T>(string json)
{
System.Text.UTF8Encoding utf = new System.Text.UTF8Encoding();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
using (System.IO.MemoryStream s = new System.IO.MemoryStream(utf.GetBytes(json)))
{
return (T)ser.ReadObject(s);
}
}
}
除了涉及到泛型外,代码还是非常容易看懂的吧。
使用也非常容易,例如:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string json = context.Request.Form["ob"];
Employee emp = JsonHelper.DeSerializeObject<Employee>(json);
string ret = JsonHelper.SerializeObject(emp);
context.Response.Write(ret);
}
{
context.Response.ContentType = "text/plain";
string json = context.Request.Form["ob"];
Employee emp = JsonHelper.DeSerializeObject<Employee>(json);
string ret = JsonHelper.SerializeObject(emp);
context.Response.Write(ret);
}
需要注意的是 Employee是个自定义的实体类。
public class Employee
{
string name = "";
public string Name
{
get { return name; }
set { name = value; }
}
string title = "";
public string Title
{
get { return title; }
set { title = value; }
}
}
public class Employee
{
string name = "";
public string Name
{
get { return name; }
set { name = value; }
}
string title = "";
public string Title
{
get { return title; }
set { title = value; }
}
}
有不少学员喜欢在实体类上加[Serializable],这时可要小心了,加上这个标记的化,JsonHelper.SerializeObject 结果中使用的是 Employee中变量名称(例如:name、title)而非属性(例如:Name、Title),JsonHelper.DeSerializeObject方法要求传递过来的json字符串也必须是变量名称格式的。当然您可以选择不用[Serializable]标记,但是有时候别的功能可能希望进行序列化,为了解决这个问题,您可以使用如下方式来定义 Employee:
[System.Runtime.Serialization.DataContract]
public class Employee
{
string name = "";
[System.Runtime.Serialization.DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
string title = "";
[System.Runtime.Serialization.DataMember]
public string Title
{
get { return title; }
set { title = value; }
}
}
public class Employee
{
string name = "";
[System.Runtime.Serialization.DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
string title = "";
[System.Runtime.Serialization.DataMember]
public string Title
{
get { return title; }
set { title = value; }
}
}
这样的化有不少好处:
客户端和服务器都可以依据 属性名称 ,轻松实现序列化和反序列化。
WCF中,这样的写法就更常见了,想了解更多可以参考WCF相关书籍。