强大的JSON

前一段时间去一个客户那做支持的时候,看到一哥们使用了MS ajax类库,使用的效果让我觉得很新鲜,在服务器端定义的一些方法,只要加上ajax库的某个属性,则可在client-side中直接进行调用,如果服务器端方法有返回值的话,在客户端还能接收并像使用服务器端对象一般,我之前一直很疑惑,为什么能做到如此,当时看到在服务器端返回一个datatable对象,然后就看到在客户端使用这个datatable对象了,使用的代码和方式就像再写服务器端代码一样,当时很是疑惑,因为自己刚接触web不久,最终没能正面的帮客户解决使用中的一个问题,而是提供了另一种比较笨的方式callback。后来有幸看到一篇介绍JSON的文章,渐渐的思路有点清晰起来,猜想应该是在服务器端将某个对象序列化成JSON,然后在客户端再将JSON实例化成某个对象,为了印证我的思路,google上一搜,果然已经有了很多将对象序列化成JSON的代码,附上codeproject上的一个实现:
http://www.codeproject.com/KB/aspnet/ASPNET_DataTable_to_JSON.aspx
还有人专门从Anthem.net中专门剥离出了这部分代码,这里也一并附上:
public class Converter
    {
        private static void WriteDataRow(StringBuilder sb, DataRow row)
        {
            sb.Append("{");
            foreach (DataColumn column in row.Table.Columns)
            {
                sb.AppendFormat("/"{0}/":", column.ColumnName);
                WriteValue(sb, row[column]);
                sb.Append(",");
            }
            // Remove the trailing comma.
            if (row.Table.Columns.Count > 0)
            {
                --sb.Length;
            }
            sb.Append("}");
        }

        private static void WriteDataSet(StringBuilder sb, DataSet ds)
        {
            sb.Append("{/"Tables/":{");
            foreach (DataTable table in ds.Tables)
            {
                sb.AppendFormat("/"{0}/":", table.TableName);
                WriteDataTable(sb, table);
                sb.Append(",");
            }
            // Remove the trailing comma.
            if (ds.Tables.Count > 0)
            {
                --sb.Length;
            }
            sb.Append("}}");
        }

        private static void WriteDataTable(StringBuilder sb, DataTable table)
        {
            sb.Append("{/"Rows/":[");
            foreach (DataRow row in table.Rows)
            {
                WriteDataRow(sb, row);
                sb.Append(",");
            }
            // Remove the trailing comma.
            if (table.Rows.Count > 0)
            {
                --sb.Length;
            }
            sb.Append("]}");
        }

        private static void WriteEnumerable(StringBuilder sb, IEnumerable e)
        {
            bool hasItems = false;
            sb.Append("[");
            foreach (object val in e)
            {
                WriteValue(sb, val);
                sb.Append(",");
                hasItems = true;
            }
            // Remove the trailing comma.
            if (hasItems)
            {
                --sb.Length;
            }
            sb.Append("]");
        }

        private static void WriteHashtable(StringBuilder sb, Hashtable e)
        {
            bool hasItems = false;
            sb.Append("{");
            foreach (string key in e.Keys)
            {
                sb.AppendFormat("/"{0}/":", key.ToLower());
                WriteValue(sb, e[key]);
                sb.Append(",");
                hasItems = true;
            }
            // Remove the trailing comma.
            if (hasItems)
            {
                --sb.Length;
            }
            sb.Append("}");
        }

        private static void WriteObject(StringBuilder sb, object o)
        {
            MemberInfo[] members = o.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public);
            sb.Append("{");
            bool hasMembers = false;
            foreach (MemberInfo member in members)
            {
                bool hasValue = false;
                object val = null;
                if ((member.MemberType & MemberTypes.Field) == MemberTypes.Field)
                {
                    FieldInfo field = (FieldInfo)member;
                    val = field.GetValue(o);
                    hasValue = true;
                }
                else if ((member.MemberType & MemberTypes.Property) == MemberTypes.Property)
                {
                    PropertyInfo property = (PropertyInfo)member;
                    if (property.CanRead && property.GetIndexParameters().Length == 0)
                    {
                        val = property.GetValue(o, null);
                        hasValue = true;
                    }
                }
                if (hasValue)
                {
                    sb.Append("/"");
                    sb.Append(member.Name);
                    sb.Append("/":");
                    WriteValue(sb, val);
                    sb.Append(",");
                    hasMembers = true;
                }
            }
            if (hasMembers)
            {
                --sb.Length;
            }
            sb.Append("}");
        }

        private static void WriteString(StringBuilder sb, string s)
        {
            sb.Append("/"");
            foreach (char c in s)
            {
                switch (c)
                {
                    case '/"':
                        sb.Append("///"");
                        break;
                    case '//':
                        sb.Append("");
                        break;
                    case '/b':
                        sb.Append("//b");
                        break;
                    case '/f':
                        sb.Append("//f");
                        break;
                    case '/n':
                        sb.Append("//n");
                        break;
                    case '/r':
                        sb.Append("//r");
                        break;
                    case '/t':
                        sb.Append("//t");
                        break;
                    default:
                        int i = (int)c;
                        if (i < 32 || i > 127)
                        {
                            sb.AppendFormat("//u{0:X04}", i);
                        }
                        else
                        {
                            sb.Append(c);
                        }
                        break;
                }
            }
            sb.Append("/"");
        }
        public static void WriteValue(StringBuilder sb, object val)
        {
            if (val == null || val == System.DBNull.Value)
            {
                sb.Append("null");
            }
            else if (val is string || val is Guid)
            {
                WriteString(sb, val.ToString());
            }
            else if (val is bool)
            {
                sb.Append(val.ToString().ToLower());
            }
            else if (val is double ||
                val is float ||
                val is long ||
                val is int ||
                val is short ||
                val is byte ||
                val is decimal)
            {
                sb.AppendFormat(CultureInfo.InvariantCulture.NumberFormat, "{0}", val);
            }
            else if (val.GetType().IsEnum)
            {
                sb.Append((int)val);
            }
            else if (val is DateTime)
            {
                sb.Append("new Date(/"");
                sb.Append(((DateTime)val).ToString("MMMM, d yyyy HH:mm:ss", new CultureInfo("en-US", false).DateTimeFormat));
                sb.Append("/")");
            }
            else if (val is DataSet)
            {
                WriteDataSet(sb, val as DataSet);
            }
            else if (val is DataTable)
            {
                WriteDataTable(sb, val as DataTable);
            }
            else if (val is DataRow)
            {
                WriteDataRow(sb, val as DataRow);
            }
            else if (val is Hashtable)
            {
                WriteHashtable(sb, val as Hashtable);
            }
            else if (val is IEnumerable)
            {
                WriteEnumerable(sb, val as IEnumerable);
            }
            else
            {
                WriteObject(sb, val);
            }
        }
        public static string Convert2Json(object o)
        {
            StringBuilder sb = new StringBuilder();
            WriteValue(sb, o);
            return sb.ToString();
        }
    }
其实ms的ajax library肯定也有相关的类实现这样的功能,Sys.Serialization.JavaScriptSerializer,没错,就是这个家伙了。
因为最近也在玩玩java,对它是越来越有好感了,虽然目前为止用的不多,但有一点体会,学习java更容易接近事物的本质,net下的封装逐渐将人变成ms的组件搬运工了:)
假设我有一个类型Car
function Car(make, model, year, color)       {  
     this.make  =  make;  
     this.model  =  model;  
     this.year  =  year;  
     this.color  =  color;  
}
我生成一个Car对象并将它发送到服务器端
  1. function sendRequest() {   
  2.     var carr = new Car("Dodge""Coronet R/T", 1968, "yellow");   
  3.     var pars = "car=" + carr.toJSONString();   
  4.   
  5.     var url = "/MyWebApp/JSONTest1";   
  6.     var mailAjax = new Ajax.Request(   
  7.         url,   
  8.         {   
  9.             method: 'get',   
  10.             parameters: pars,   
  11.             onComplete: jsonResponse   
  12.         }   
  13.     );   
  14. }  
服务器端接收该对象,并使用现成的类去解析它,比如下面介绍的JSONObject,可以到这个地方下载, http://www.json.org/java/index.html .不止这一个类,还有很多其他的类。

private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {  
    String s3 = request.getParameter("car");  
    try {  
        JSONObject jsonObj = new JSONObject(s3);  
        System.out.println(jsonObj.getString("model"));  
        System.out.println(jsonObj.getInt("year"));  
    } catch (JSONException e) {  
        e.printStackTrace();  
    }  
    response.getWriter().print("{ /"name/": /"Violet/", /"occupation/": /"character/" }");  
}
  •  
很方便,很easy...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值