初探.NET BCL 中 JavaScriptConverter 抽象类
前言
与此相关的类
JavaScriptSerializer | 为启用 AFAX 的应用程序提供序列化和反序列化功能。 |
JavaScriptTypeResolver | 提供用于实现自定义类型解析器的抽象基类。 |
JavaScriptConverter | 为自定义类型转换器提供抽象基类。 |
JavaScriptConverter 抽象类中定义了两个抽象方法:
public abstract IDictionary<string, Object> Serialize( Object obj, JavaScriptSerializer serializer ) public abstract Object Deserialize( IDictionary<string, Object> dictionary, Type type, JavaScriptSerializer serializer )
其实这个类的用途:在使用 JavaScriptSerializer 类做序列化的时候,有些对象不能被序列化,如 DataTable 对象。这个时候我能通过自定义一个 JavaScriptConverter 类就可以完成序列化工作。
实现
/// <summary> /// Custom <see cref="JavaScriptConverter"/> . /// </summary> public class CustomJavaScriptConverter : JavaScriptConverter{ private IEnumerable<Type> _supportedTypes; /// <summary> /// Initializes a new instance of the <see cref="FirstWebApplication.CustomJavaScriptConverter"/> class. /// </summary> /// <param name='supportedTypes'> Supported types.</param> public CustomJavaScriptConverter(IEnumerable<Type> supportedTypes){ this._supportedTypes = supportedTypes; } public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer){ DataTable dt = obj as DataTable; Dictionary<String, object> result = new Dictionary<String, object>(); if(dt != null){ List<Dictionary<String, object>> arrList = new List<Dictionary<String, object>>(); foreach(DataRow row in dt.Rows){ Dictionary<String, object> dic = new Dictionary<String, object>(); foreach(DataColumn col in dt.Columns){ dic.Add(col.ColumnName, row[col.ColumnName]); } arrList.Add(dic); } result[dt.TableName] = arrList; } return result; } public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer){ if(type == typeof(DataTable)){ foreach(KeyValuePair<String, object> item in dictionary){ DataTable dt = new DataTable(item.Key); ArrayList rows = item.Value as ArrayList; Dictionary<String, object> schema = serializer.ConvertToType<Dictionary<String, object>>(rows[0]); //填充 DataTable 表结构 foreach(String columnName in schema.Keys){ dt.Columns.Add(columnName); } //向 DataTable 填充数据 foreach(object objRow in rows){ DataRow dr = dt.NewRow(); Dictionary<String, object> dicRow = serializer.ConvertToType<Dictionary<String, object>>(objRow); foreach(KeyValuePair<String, object> rowline in dicRow){ dr[rowline.Key]=rowline.Value; } dt.Rows.Add(dr); } return dt; } } return null; } public override IEnumerable<Type> SupportedTypes { get { return _supportedTypes; } } }
使用示例
private void _CustomJSConverter(HttpContext context){ DataTable dt = new DataTable("dt"); dt.Columns.AddRange(new DataColumn[]{ new DataColumn("Id", typeof(int)), new DataColumn("Name", typeof(String)), new DataColumn("Price", typeof(decimal)) }); int i=0; for(; i < 3; i++){ DataRow dr = dt.NewRow(); dr["Id"]=i+1; dr["Name"]="Oger"+i; dr["Price"]=12m+i; dt.Rows.Add(dr); } JavaScriptSerializer serializer = new JavaScriptSerializer(); CustomJavaScriptConverter converter = new CustomJavaScriptConverter(new Type[]{ typeof(DataTable) }); //注册一个 JavaScriptConverter serializer.RegisterConverters(new JavaScriptConverter[]{ converter }); var json = serializer.Serialize(dt); DataTable newDt = serializer.Deserialize<DataTable>(json); context.Response.Write(json); }
假如不想使用第三方序列化组件的话,可能考虑这个方式。这些类位于:System.Web.Extensions.dll 中。
后台发现的不错的博客:http://weblog.west-wind.com/posts/2009/Apr/24/JSON-Serialization-of-a-DataReader
本博客内容,如需转载请务必保留超链接。Contact Me:Mail此处省略好几个字...