纸上得来终觉浅,绝知此事要躬行。

 

初探.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 

posted on 2014-03-30 11:52  JRoger  阅读(796)  评论(0编辑  收藏  举报

导航