准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法
Json语法规则:
-
数据在键值对中
-
数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
一、JSON的表现形式
在javascript中对象的表现形式如下
1.对象表现形式:
2.数组表现形式:
3.对象数组联合表现形式:
二、什么是JSON序列化与反序列化?
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
简单来说就是对象转换成为JSON格式字符串我们称为序列化,反之JSON字符串转换为对象我们称为反序列化。
下边我们准备点基础类,部门信息类
using System; namespace MySerialize.Entity { public class DeptInfo { public int Id { get; set; } public string DeptName { get; set; } public DateTime CreateTime { get; set; } } }
枚举类,分别是职务类别,人员状态。这里简单说下枚举的特点是如果枚举值不指定起始位置默认从0开始,如果指定枚举第一个值则从指定的第一位开始一次递增加一计算枚举值,如果每个枚举值都赋值则按赋值计算,
不理解这句话没关系不影响学习JSON正反序列化。
using System; namespace MySerialize.Entity { ////// 职务类别 /// public enum JobType { 董事长, 总经理, 总监, 部门经理, 人事专员, 职员, 工程师, 其他 } public enum PersonType { 在职,离职,退休,停职 } }
用户信息类
using System; using System.Collections.Generic; namespace MySerialize.Entity { public class UserInfo { public int Id { get; set; } public string UserName { get; set; } ////// 姓 /// public string FirstName { get; set; } /// /// 名 /// public string LastName { get; set; } public string PassWord { get; set; } public string Phone { get; set; } public string Address { get; set; } public DeptInfo Dept { get; set; } public JobType DeptType { get; set; } public PersonType UserType { get; set; } /// /// 职业技能 /// public Dictionary<int, string> UserSkill { get; set; } /// /// 特长 /// public Dictionary<string, string> UserStrong { get; set; } } }
数据初始化类
using MySerialize.Entity; using System; using System.Collections.Generic; namespace MySerialize { public class DataFactory { ////// 获取所有专业技能 /// /// public static Dictionary<int, string> GetSkillAll() { Dictionary<int, string> DictionarySkill = new Dictionary<int, string>(); DictionarySkill.Add(1, "1234"); DictionarySkill.Add(2, "abcd"); DictionarySkill.Add(3, "大中国"); DictionarySkill.Add(4, "学习"); DictionarySkill.Add(5, "上网"); return DictionarySkill; } /// /// 获取所有的特长 /// /// public static Dictionary<string, string> GetStrongAll() { Dictionary<string, string> DictionaryStrong = new Dictionary<string, string>(); DictionaryStrong.Add("1", "abcdefg"); DictionaryStrong.Add("2", "abcdefg123"); DictionaryStrong.Add("3", "tvbcd"); DictionaryStrong.Add("4", "您吃了吗"); DictionaryStrong.Add("5", "吃了吗您呢"); DictionaryStrong.Add("6", "tvbc 早上好"); DictionaryStrong.Add("7", "vbbc 晚上好"); return DictionaryStrong; } public static List BuildUserList() { DeptInfo dept0 = new DeptInfo() { CreateTime = DateTime.Now, DeptName = "开发部", Id = 1 }; DeptInfo dept1 = new DeptInfo() { CreateTime = DateTime.Now, DeptName = "电商事业部", Id = 2 }; DeptInfo dept2 = new DeptInfo() { CreateTime = DateTime.Now, DeptName = "成功部", Id = 3 }; DeptInfo dept3 = new DeptInfo() { CreateTime = DateTime.Now, DeptName = "人力资源管理部", Id = 4 }; List list = new List (); list.Add(new UserInfo() { Address = "北京昌平", DeptType = JobType.工程师, Dept = dept0, Id = 1, FirstName = "张", LastName = "三", PassWord = "", Phone = "13122222222222", UserName = "wbc", UserType = PersonType.在职, UserSkill = GetSkillAll(), UserStrong = GetStrongAll() }); list.Add(new UserInfo() { Address = "北京昌平", DeptType = JobType.工程师, Dept = dept0, Id = 5, FirstName = "张", LastName = "三", PassWord = "", Phone = "13122222222222", UserName = "wbc", UserType = PersonType.在职, UserSkill = GetSkillAll(), UserStrong = GetStrongAll() }); list.Add(new UserInfo() { Address = "北京昌平", DeptType = JobType.工程师, Dept = dept3, Id = 3, FirstName = "张", LastName = "三", PassWord = "", Phone = "13122222222222", UserName = "wbc", UserType = PersonType.在职, UserSkill = GetSkillAll(), UserStrong = GetStrongAll() }); list.Add(new UserInfo() { Address = "北京昌平", DeptType = JobType.工程师, Dept = dept2, Id = 2, FirstName = "wwdd", LastName = "三", PassWord = "", Phone = "13122222222222", UserName = "wbc", UserType = PersonType.在职, UserSkill = GetSkillAll(), UserStrong = GetStrongAll() }); list.Add(new UserInfo() { Address = "北京昌平", DeptType = JobType.工程师, Dept = dept1, Id = 4, FirstName = "wang", LastName = "三", PassWord = "", Phone = "13122222222222", UserName = "wbc", UserType = PersonType.在职, UserSkill = GetSkillAll(), UserStrong = GetStrongAll() }); return list; } } }
三、常见Json序列化和反序列化类
1.DataContractJsonSerializer 类序列化和反序列化:
DataContractJsonSerializer 类在 System.Runtime.Serialization.Json这个命名空间下,在net 4.0里面,而这个命名空间在 System.Runtime.Serialization.dll中
Listlist= DataFactory.BuildUserList();//获取基础数据 //对象的系列化 DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List )); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, list); string jsonString = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); //反序列化 ser = new DataContractJsonSerializer(typeof(List )); ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); List obj = (List )ser.ReadObject(ms);
2.JavaScriptSerializer 类序列化和反序列化:
JavaScriptSerializer 类在 System.Web.Script.Serialization命名空间下了,在net3.0里面,而这个命名空间在 System.Web.Extensions.dll 中
Dictionary<string, string> dictionaryStrong= new Dictionary<string, string>(); dictionaryStrong.Add("1","22222222222222"); UserInfo user = new UserInfo() { Id=1, Dept =new DeptInfo() { CreateTime=DateTime.Now,Id=1,DeptName="开发部"}, Address="北京北京市", DeptType=JobType.工程师, FirstName="王", LastName="柏成", PassWord="", Phone="13126994771", UserName="wbc", UserSkill=null, UserStrong= dictionaryStrong, UserType=PersonType.在职 }; //序列化 System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer(); string jsonString = jss.Serialize(user); txtData.Text = jsonString; //反序列化 UserInfo obj = jss.Deserialize(jsonString);
3.JsonConvert类序列化和反序列化:
JsonConvert类在 Newtonsoft.Json 命名空间下了,而这个命名空间在Newtonsoft.Json.dll 中,而这个dll 只是第三方的一个中间件,我们可以通过nuget 获取并引用。
Listlist = DataFactory.BuildUserList();//获取基础数据 //对象的系列化 string jsonString= JsonConvert.SerializeObject(list); txtData.Text = jsonString; //反序列化 List obj = JsonConvert.DeserializeObject >(jsonString);
4. 简单学习 linq to Json:
linq to Json 是在Newtonsoft.Json.dll 的 Newtonsoft.Json.linq 命名空间下. json 操作类如下
className(类名) | describe(说明) |
JObject |
用于操作JSON对象 |
JArray |
用语操作JSON数组 |
JValue |
表示数组中的值 |
JProperty |
表示对象中的属性,以"key/value"形式 |
JToken |
用于存放Linq to JSON查询后的结果 |
创建Json对象和数组组合:
JArray jArray = new JArray(); JObject staff = new JObject(); staff.Add(new JProperty("Name", "wangbaicheng")); staff.Add(new JProperty("Age", 33)); staff.Add(new JProperty("Department", "销售部")); staff.Add(new JProperty("Leader", new JObject(new JProperty("Name", "feifei"), new JProperty("Age", 30), new JProperty("Department", "chanpin")))); jArray.Add(staff); jArray.Add(staff); jArray.Add(staff); staff.Add(new JProperty("Array", jArray)); jArray = new JArray(); jArray.Add(new JValue("1")); jArray.Add(new JValue("2")); jArray.Add(new JValue("3")); jArray.Add(new JValue("4")); staff.Add(new JProperty("arr", jArray)); txtData.Text = staff.ToString();
我们还可以通过如字符串获取Json 对象,具体不演示了,看如下表格
方法 | 说明 |
JObject.Parse(string json) |
json含有JSON对象的字符串,返回为JObject对象,最外层是对象 |
JObject.FromObject(object o) |
o为要转化的对象,返回一个JObject对象 |
JObject.Load(JsonReader reader) |
reader包含着JSON对象的内容,返回一个JObject对象 |
JArray.Parse(string json) |
json含有JSON数组的字符串,返回为JArray对象,最外层是数组 |
JArray.FromObject(object o) |
o为要转化的对象,返回一个JArray对象 |
JArray.Load(JsonReader reader) |
reader包含着JSON对象的内容,返回一个JArray对象 |
现有如下Json
{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"},\"Array\":[{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}},{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}},{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}}],\"arr\":[\"1\",\"2\",\"3\",\"4\"]}
我们来看下使用linq 和使用对象来解析Json
//对象解析json和linq 解析json { string json = "{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"},\"Array\":[{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}},{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}},{\"Name\":\"wangbaicheng\",\"Age\":33,\"Department\":\"销售部\",\"Leader\":{\"Name\":\"feifei\",\"Age\":30,\"Department\":\"chanpin\"}}],\"arr\":[\"1\",\"2\",\"3\",\"4\"]}"; JObject jObject = JObject.Parse(json); //使用对象解析 string name= jObject["Name"].ToString();//注意大小写 name = jObject.Value<string>("Name");//注意大小写 JArray array= jObject.Value("Array"); for (int i = 0; i < array.Count; i++) { JToken token= array[i]; JObject obj = token as JObject; Console.WriteLine("对象解析"+obj.Value<string>("Name")); } //linq 解析 var names = from staff in jObject["Array"].Children() select (string)staff["Name"]; foreach (var n in names) Console.WriteLine("linq解析"+n); }
这里就不过多的深入了,毕竟我们大多数的时候还是比较喜欢json 转换成为我们自己定义的对象的。
四、封装自己的JsonHelper 类
public static class JsonHelper { #region System.Runtime.Serialization net 4.0 ////// 对象序列化为JSON /// /// /// /// public static string ObjectToJson (this T _t) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(); ser.WriteObject(ms, _t); string jsonString = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); return jsonString; } /// /// 对象反序列化 /// /// /// /// public static T JsonToObject (this string jsonString) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)ser.ReadObject(ms); return obj; } #endregion #region net3.0 System.Web.Extensions.dll /// /// 使用net 3.0 json 反序列化,支持json字符串属性不带引号 /// /// /// /// public static T JsonToObj (this string jsonString) { //引用 System.Web.Extensions.dll System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer(); return jss.Deserialize (jsonString); } /// /// 使用net 3.5 对象序列化成为json 反序列化,支持json字符串属性不带引号 /// /// /// /// public static string ObjToJson (this T t) { //引用 System.Web.Extensions.dll System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer(); return jss.Serialize(t); } #endregion /// /// JsonConvert.SerializeObject /// /// /// /// public static string ToJson (this T obj) { return JsonConvert.SerializeObject(obj); } /// /// JsonConvert.DeserializeObject /// /// /// /// public static T ToObject (this string content) { return JsonConvert.DeserializeObject (content); } }
五、Json 深入
我们都知道,在js中json的key 是可以使用数字的,我们学习了三种序列化方式,如何把一个json 的key 为数字转换成为对象,我们很多开发人员可能都会遇到过。
js 代码如下
在微软,很早之前就想到了这一解决方案,但是在4.0升级的时候,升级出来一个bug ,DataContractJsonSerializer 不再支持key 为数字转换,但是其他的两种方式都支持
我们先来看下 JavaScriptSerializer 是如何序列化和反序列化key 为数字的json 。
1.JavaScriptSerializer 类序列化和反序列化 key 为数字:
Dictionary<int, string> dictionary1 = DataFactory.GetSkillAll(); Dictionary<string, string> dictionary2 = DataFactory.GetStrongAll(); try { string json = dictionary1.ObjToJson(); Dictionary<int, string> d = json.JsonToObjint, string>>(); } catch { } try { string json = dictionary2.ObjToJson(); Dictionary<string, string> d = json.JsonToObj string, string>>(); } catch { }
我们上述代码分别为两个字典,字典值均为数字,只是一个是字符串类型的,一个是整数类型的,整数类型的无法序列化和反序列化,字符串类型的可以序列化和反序列化。
看看序列化结果。
{"1":"abcdefg","2":"abcdefg123","3":"tvbcd","4":"您吃了吗","5":"吃了吗您呢","6":"tvbc 早上好","7":"vbbc 晚上好"}
也就是说,微软在早期是只支持字符串类型的数字key
2.JsonConvert类序列化和反序列化:
这个放心,不论key 是int 类型还是string 类型,都支持的,我们看下案列
Dictionary<int, string> dictionary1 = DataFactory.GetSkillAll(); Dictionary<string, string> dictionary2 = DataFactory.GetStrongAll(); string json1= dictionary1.ToJson(); string json2=dictionary2.ToJson(); Console.WriteLine(json1); Console.WriteLine(json2);
完
源码下载地址: 点击下载