json,刚开始的时候感觉很神秘什么,查资料看也看不懂,写了段时间脚本后突然就自己明白了,json----javascript object national,就是个JS对象...而对于服务端程序而言(不论你是用什么语言...望看到的人不要在这上面纠结...),都可以把脚本当作一段字符串.在服务端要做的,就是按语法拼接出字符串.
曾经在网上搜过自动生成json的现成的类,但没找到,于是就自己写了个.不过也好,自己写的东西自己也比较了解,用起来感觉也比较灵活.也许我是在做再次"发明轮子"的傻事,不过还是放出代码.
using System;
using System.Text;
using System.Collections.Generic;
/// <summary>
/// json 格式字符串生成类,可生成对象及对象数组,但不能生成过于复杂的对象
/// </summary>
public class Json
{
StringBuilder stb = new StringBuilder();
bool isarr;
//前面定义的一些特定格式的字符串.
string strfmt = ",{0}:'{1}'";
string numfmt = ",{0}:{1}";
string objstr = "{{{0}:'{1}'";
string objnum = "{{{0}:{1}";
string rk = "}";
string dh = ",";
bool isend = true; //是否拼接结束
bool bracket = false; //是否在前后添加小括号
bool addfun = false; //是否构建匿名方法;
List<NameValue> li = null; //NameVale用于表示JS对象的属性
//有的时候返回分页的结果,还要返回总数,这时候可以拼接成匿名方法,然后把总数设置成属性就OK了
private string endstr = null;
private struct NameValue
{
public string name;
public string value;
public NameValue(string _name,string _value)
{
name = _name;
value = _value;
}
}
/// <summary>
/// 此构造不包含使用匿名函数部分,由于之前有调用到,因此保留,正常情况下应使用另一构造
/// </summary>
/// <param name="_isarr">json是否为一数组对象,以区分格式</param>
/// <param name="_bracket">是否在json对象外面添加小括号</param>
public Json(bool _isarr, bool _bracket)
{
isarr = _isarr;
bracket=_bracket;
if (bracket)
stb.Append("(");
if (isarr)
stb.Append("[");
}
/// <summary>
///
/// </summary>
/// <param name="_isarr">json是否为一数组对象,以区分格式</param>
/// <param name="_bracket">是否在json对象外面添加小括号</param>
/// <param name="_addfun">是否使用匿名函数(当需要对对象添加额外属性时使用),默认为false</param>
public Json(bool _isarr, bool _bracket, bool _addfun)
{
addfun = _addfun;
if (addfun)
{
stb.Append("(function(){var o=");
li = new List<NameValue>();
}
isarr = _isarr;
bracket = _bracket;
if (bracket)
stb.Append("(");
if (isarr)
stb.Append("[");
}
/// <summary>
/// 为对象添加属性
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
public void addAttribute(string name, string value)
{
if (addfun)
{
li.Add(new NameValue(name, value));
}
else
throw new Exception("须在声明为使用匿名函数的情况下才能调用此方法!");
}
public void addObject(string name, string value)
{
isend = false;
stb.AppendFormat(objstr, name, value);
}
public void addObject(string name, int value)
{
isend = false;
stb.AppendFormat(objnum, name, value);
}
public void addObject(string name, float value)
{
isend = false;
stb.AppendFormat(objnum, name, value);
}
/// <summary>
/// 将对象声明为数组对象时调用,否则抛出异常
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="isnext"></param>
public void addObject(string name, string value, bool isnext)
{
if (isarr)
{
isend = false;
if (isnext)
stb.Append(dh);
stb.AppendFormat(objstr, name, value);
}
else
throw new Exception("只有将对象声明为生成数组对象时才可调用此方法!");
}
public void addObject(string name, int value, bool isnext)
{
if (isarr)
{
isend = false;
if (isnext)
stb.Append(dh);
stb.AppendFormat(objnum, name, value);
}
else
throw new Exception("只有将对象声明为生成数组对象时才可调用此方法!");
}
public void addObject(string name, float value, bool isnext)
{
if (isarr)
{
isend = false;
if (isnext)
stb.Append(dh);
stb.AppendFormat(objnum, name, value);
}
else
throw new Exception("只有将对象声明为生成数组对象时才可调用此方法!");
}
public void add(string name, string value)
{
stb.AppendFormat(strfmt, name, value);
}
public void add(string name, int value)
{
stb.AppendFormat(numfmt, name, value);
}
public void add(string name, float value)
{
stb.AppendFormat(numfmt, name, value);
}
/// <summary>
/// 方法中会调用j的End方法,j经过调用后将能不再修改
/// </summary>
/// <param name="name"></param>
/// <param name="j"></param>
public void add(string name, Json j)
{
stb.AppendFormat(numfmt, name, j.End());
}
public void objEnd()
{
stb.Append(rk);
isend = true;
}
/// <summary>
/// 结束json的拼接并返回json字符串,此方法只能调用以后,不能再调用其它方法,即使调用其它方法也不再影响生成的jsong内容,调用前需objEnd方法
/// </summary>
/// <returns></returns>
public string End()
{
if (!isend)
objEnd();
if (string.IsNullOrEmpty(endstr))
{
if (isarr)
stb.Append("]");
if (bracket)
stb.Append(")");
if (addfun)
{
string fmt = "o['{0}']='{1}';";
stb.Append(";");
foreach (NameValue nv in li)
{
stb.AppendFormat(fmt, nv.name, nv.value);
}
stb.Append("return o;})();");
}
endstr = stb.ToString();
stb.Remove(0, stb.Length);
}
return endstr;
}
}
调用示例
IPhotoBLL pb = new PhotoBLL();
IList<T_Photo> li;
int count, uid;
int size;
if (!int.TryParse(Request.QueryString["size"], out size))
size = 5;
if (int.TryParse(Request.QueryString["uid"], out uid))
{
li = pb.newphotos(uid, size);
if (Request.QueryString["type"] == "json")
{
Json json = new Json(true, true);
string id = "id", name = "name", time = "time", url = "url", boxid = "boxid", userid = "userid";
bool isnext = false;
string fmt = "yyyy-MM-dd";
foreach (T_Photo p in li)
{
json.addObject(id, p.ID, isnext);//这里的isnext表示是否为第二条记录,可放入到拼接类中.由于是使用了一段时间后在用到这个东西,所以没有改拼接类了
json.add(name, p.F_Name);
json.add(time, p.F_UploacTime.ToString(fmt));
json.add(url, p.F_ImageUrl);
json.add(boxid, p.F_BoxID);
json.add(userid, p.F_UserID);
json.objEnd();
if (!isnext)
isnext = true;
}
Response.Write(json.End());
}
else
{
//这里是XmlSerializer类的使用...后台是简单了,js部分累得要死...
Response.ContentType = "text/xml";
XmlSerializer xs = new XmlSerializer(typeof(List<T_Photo>));
xs.Serialize(Response.OutputStream, li);
}
}
前台脚本部分就不写了,一般情况下eval之后是一个数组
附:如果在代码中加进反射,应该可以像XMLSerializer类一样简单(指的是使用上面),不过我没有搞,一是对反射不熟.另外就是用反射的话还要做很多判断什么的,要增加很多代码,麻烦,而且封装得太多,灵活性就降低了.
代码中还有throw exception的部分,这是为了写代码的时候好知道哪里出现问题.如果不愿意抛出异常,可补充部分操作,以取代异常抛出
以上即自己的json拼接类,目前使用上未出现过问题,写出来仅供参考,无任何代表性...如果要拿去使用,也没有限制...有不对的地方,欢迎指出