将指定的数据类型序列化为Json。Serialize方法是个递归方法,会递归地序列化对象的属性,因此在序列化一个复杂对象(比如DataTable)时往往会出现“循环引用”的异常,这时候就需要针对复杂类型自定义一个转换器。下面是DataTable的转换器,原理是把DataTable转换成一个字典列表后再序列化:
所有自定义的转换器都要继承于JavaScriptConverter,并实现Serialize、Deserialize方法和SupportedTypes属性,其中SupportedTypes属性用于枚举此转换器支持的类型。
class Program { static void Main(string[] args) { DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Age"); dt.Rows.Add(1, "关羽", 21); dt.Rows.Add(2, "刘备", 22); dt.Rows.Add(3, "张飞", 20); JavaScriptSerializer jss = new JavaScriptSerializer(); //注册转换器的方法,用于复杂转换 除了实现还需要注册到JavaScriptSerializer jss.RegisterConverters(new JavaScriptConverter[] { new DataTableConverter() }); string strJson = jss.Serialize(dt); Console.WriteLine(strJson); //输出 {"Rows":[{"Id":"1","Name":"关羽","Age":"21"},{"Id":"2","Name":"刘备","Age":"22"},{"Id":"3","Name":"张飞","Age":"20"}]} Console.ReadKey(); } } /// <summary> /// DataTable JSON转换类 /// </summary> public class DataTableConverter : JavaScriptConverter { public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { DataTable dt = obj as DataTable; Dictionary<string, object> result = new Dictionary<string, object>(); List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); foreach (DataRow dr in dt.Rows) { Dictionary<string, object> row = new Dictionary<string, object>(); foreach (DataColumn dc in dt.Columns) { row.Add(dc.ColumnName, dr[dc.ColumnName]); } rows.Add(row); } result["Rows"] = rows; return result; } public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { throw new NotImplementedException(); } /// <summary> /// 获取本转换器支持的类型 /// </summary> public override IEnumerable<Type> SupportedTypes { get { return new Type[] { typeof(DataTable) }; } } }
限制序列化的层次
class Program { static void Main(string[] args) { JavaScriptSerializer jss = new JavaScriptSerializer(); Console.WriteLine(jss.RecursionLimit); //默认的序列化层次是100 Person p1 = new Person(1, "刘备", 24); p1.p = new Person(2, "关羽", 23); p1.p.p = new Person(3, "张飞", 21); string strJson = jss.Serialize(p1); Console.WriteLine(strJson); //输出 {"Id":1,"Name":"刘备","Age":24,"p":{"Id":2,"Name":"关羽","Age":23,"p":{"Id":3,"Name":"张飞","Age":21,"p":null}}} //现在将层次减少到1 jss.RecursionLimit = 1; string strJson2 = jss.Serialize(p1);//这行代码是报异常的,显示已超出 RecursionLimit。 这就是这个属性的作用 //最后再来说一个特性,比如如果我有某一个属性不希望它序列化,那么可以设置添加 Console.ReadKey(); } } public class Person { public Person() { } public Person(int id, string name, int age) { this.Id = id; this.Name = name; this.Age = age; } public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } //里面嵌套一个Person public Person p { get; set; } }
[ScriptIgnore]禁止某属性序列化
class Program { static void Main(string[] args) { JavaScriptSerializer jss = new JavaScriptSerializer(); Person p = new Person(1,"刘备",24); Console.WriteLine(jss.Serialize(p)); File.WriteAllText(@"D:\123.txt", jss.Serialize(p)); //输出 {"Id":1,"Age":24} Console.ReadKey(); } } public class Person { public Person() { } public Person(int id, string name, int age) { this.Id = id; this.Name = name; this.Age = age; } public int Id { get; set; } [ScriptIgnore] public string Name { get; set; } public int Age { get; set; } }