将List对象列表转换成JSON格式的类

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。引用于[http://www.json.org/json-zh.html]

一般应用中,我习惯性地把结果集以更通用的IList<object>对象列表方式保存(可能会对性能有些影响)来保证类间交互时的通用性,降低函数功能对具体类的耦合。但AJAX调用时,还需要把对象列表转换成JSON数据交给前端显示。有麻烦。

     研究了一下JSON的对象定义和集合定义

 

     感觉利用反射来生成JSON还比较方便。代码如下:

 

Code

 OK,我们建立一个测试来验证一下它是否生效。

先建立一个对象定义person.cs

Code

然后建立测试类

我用了一种非常原始的方法生成了对象列表,其实可以从数据库查询,怕把事情搞得太复杂。呵呵。

Code

跑一下Nuint,我们想要的json串已经生成了。

0
0
(请您对文章做出评价)
« 上一篇:Linq to Sql 与NHibernate数据库操作性能比较研究 测试程序源码
» 下一篇:不足80行,一种清晰而又简单通用的分页算法,你有这么想过吗?C#版

posted on 2008-11-26 16:54 源姜 阅读(2985) 评论(10)  编辑 收藏

评论

#1楼 2008-11-26 17:21 上不了岸的鱼{ttzhang}      

沙发,嘿嘿...   回复  引用  查看    

#2楼 2008-11-26 18:29 圣盗      

可以参考 FrameWork3.5中的 System.Web.Script.Serialization命名空间,其中提供了JSON脚本序列化和反序列化的一些类   回复  引用  查看    

#3楼[楼主] 2008-11-26 20:02 源姜      

--引用--------------------------------------------------
圣盗: 可以参考 FrameWork3.5中的 System.Web.Script.Serialization命名空间,其中提供了JSON脚本序列化和反序列化的一些类
--------------------------------------------------------
现在因为Nhibernate还没支持3.5,我还坚守在2.0的阵地上。
  回复  引用  查看    

#4楼 2008-11-26 21:47 黑色珊瑚      

可以生成这样的JSON表达式吗?
{"Id":1,"Name":"Tahoma","FavColors":["Red","Blue","Black"],"Styles":{"Sid":100,"Value":"someStyles"}}
  回复  引用  查看    

#5楼 2008-11-27 01:29 ShawnLiu      

想法不错
通过反射来获得元数据挺合适
  回复  引用  查看    

#6楼[楼主] 2008-11-27 08:06 源姜      

--引用--------------------------------------------------
黑色珊瑚: 可以生成这样的JSON表达式吗?
{&quot;Id&quot;:1,&quot;Name&quot;:&quot;Tahoma&quot;,&quot;FavColors&quot;:[&quot;Red&quot;,&quot;Blue&quot;,&quot;Black&quot;],&quot;Styles&quot;:{&quot;Sid&quot;:100,&quot;Value&quot;:&quot;someStyles&quot;}}

--------------------------------------------------------
目前还不行。还需要再根据反射出来的属性来判断是否是自定义类,进行递归才能实现。有兴趣可以继续作下去与大家分享
  回复  引用  查看    

#7楼 2008-11-27 08:07 Kevin Zou      

做得更通用一些
處理一下基本類型,如數字就不要引號了,日期也可以序列化?
把List換成IList,甚至IEnumerator,這樣可以適用更多了,甚至任何一種object都可以直接序列化了。
現加上IgnoreJsonAttribute,可定制,是不是更OK?

或者幹脆去看net3.5的原代碼...
  回复  引用  查看    

#8楼 2008-11-27 13:03 黑色珊瑚      

这个,Anthem组件的转换JSON字符串的相关方法:

/// <summary>
/// 获得对象的JSON表达式
/// </summary>
/// <param name="val">要转换的对象</param>
/// <returns>JSON表达式</returns>
public static string GetJsonFromObject(object val)
{
StringBuilder sb = new StringBuilder();
WriteValue(sb, val);
return sb.ToString();
}
#region 私有成员方法

private 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);
}
}

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(",");
}
// 删除末尾逗号
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(",");
}
// 删除末尾逗号
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(",");
}
// 删除末尾逗号
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;
}
// 删除末尾逗号
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;
}
// 删除末尾逗号
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("\"");
}

#endregion
  回复  引用  查看    

#9楼[楼主] 2008-11-27 21:28 源姜      

--引用--------------------------------------------------
黑色珊瑚: 这个,Anthem组件的转换JSON字符串的相关方法:
--------------------------------------------------------
一直在用Anthem来作AJAX,原来还有这样的东西。
谢谢啦。
  回复  引用  查看    

#10楼 2009-12-17 15:29 闲聊闲逛      

谢谢共享,还有关于前台传入JSON,后台解析的吗?   回复  引用  查看    

导航

公告

<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

统计

搜索

 

常用链接

我的标签

随笔档案

文章分类

相册

最新评论

阅读排行榜

评论排行榜