本人是C#小白,这里摘抄并整理了两位大神的文章:
Newtonsoft.Json笔记 -JToken、JObject、JArray详解
Json 基于类 Newtonsoft.Json.Linq.JToken的应用简介
简单介绍如何使用Newtonsoft.Json类库和操作Json对象,这里主要介绍Linq to Json类。
Newtonsoft.Json
封装类实现了JToken,
直接对JSON进行增删改查的操作,很好的解决了动态解析json数据的问题,
JToken
的层次结构是这样的:
JToken
-抽象基类JContainer
- 能够包含其它JToken
的JToken
抽象基类JArray
- 表示一个JSON数组(包含一个有序的List)JObeject
- 表示一个JSON对象(包含一个IEnumerable
)JProperty
- 表示一个JSON属性(在JObject
中是一个name/JToken
键值对)JValue
- 表示一个原生JSON值(string,number,boolean,null
)
一,Linq to Json
使用Linq to Json前,需要引用Newtonsoft.Json的dll和using Newtonsoft.Json.Linq的命名空间。
Linq to Json主要使用到JObject, JArray, JProperty和JValue这四个对象,以及一个特殊的JToken对象。
- JObject:基本的Json对象,用来生成一个JSON对象,简单来说就是生成”{}”,
- JArray用来生成一个JSON数组,也就是”[]”,
- JProperty用来生成一个JSON数据,格式为key/value的值,
- 而JValue则直接生成一个JSON的Key的Value
- JToken 用于存放Linq to JSON查询后的结果
1,创建JSON对象
JObject staff = new JObject();
staff.Add(new JProperty("Name", "Jack"));
staff.Add(new JProperty("Age", 33));
staff.Add(new JProperty("Department", "Personnel Department"));
staff.Add(new JProperty("Leader", new JObject(new JProperty("Name", "Tom"), new JProperty("Age", 44), new JProperty("Department", "Personnel Department"))));
Console.WriteLine(staff.ToString());
还可以通过以下方法创建Json对象:
方法 | 说明 |
---|---|
JObject.Parse(string json) |
json含有JSON对象的字符串,返回为JObject对象 |
JObject.FromObject(object o) |
o为要转化的对象,返回一个JObject对象 |
2,创建JSON数据
// 创建数组
JArray array = new JArray();
array.Add(new JValue("吃饭"));
array.Add(new JValue("睡觉"));
Console.WriteLine(array.ToString());
上面的代码可以简化为:
JArray array = new JArray("吃饭", "睡觉")
3,查询
举一个简单的例子:
string json = "{\"Name\" : \"Jack\", \"Age\" : 34, \"Colleagues\" : [{\"Name\" : \"Tom\" , \"Age\":44},{\"Name\" : \"Abel\",\"Age\":29}] }";
//将json转换为JObject
JObject jObj = JObject.Parse(json);
JToken ageToken = jObj["Age"];
Console.WriteLine(ageToken.ToString());
二,使用JToken操作Json对象
1,查询
首先准备json字符串,是一个包含员工基本信息的json,并把字符串转换为JObject:
string json = "{\"Name\" : \"Jack\", \"Age\" : 34, \"Colleagues\" : [{\"Name\" : \"Tom\" , \"Age\":44},{\"Name\" : \"Abel\",\"Age\":29}] }";
//将json转换为JObject
JObject jObj = JObject.Parse(json);
获取员工的姓名:
//通过属性名或者索引来访问,仅仅是自己的属性名,而不是所有的
JToken ageToken = jObj["Age"];
Console.WriteLine(ageToken.ToString());
获取员工的同事的姓名:"Children()"可以返回所有数组中的对象
var names=from staff in jObj["Colleagues"].Children()
select (string)staff["Name"];
foreach (var name in names)
Console.WriteLine(name);
2,修改
//将json转换为JObject
jObj["Age"] = 35;
Console.WriteLine(jObj.ToString());
修改Jack同事的年龄为45:
//将json转换为JObject
JObject jObj = JObject.Parse(json);
JToken colleagues = jObj["Colleagues"];
colleagues[0]["Age"] = 45;
jObj["Colleagues"] = colleagues;//修改后,再赋给对象
Console.WriteLine(jObj.ToString());
3,删除
//删除第一个同事
JObject jObj = JObject.Parse(json);
jObj["Colleagues"][1].Remove();
Console.WriteLine(jObj.ToString());
//删除所有同事
JObject jObj = JObject.Parse(json);
jObj.Remove("Colleagues");//跟的是属性名称
Console.WriteLine(jObj.ToString());
4,添加
//添加部门信息,必须添加在Age节点的后面
JObject jObj = JObject.Parse(json);
jObj["Age"].Parent.AddAfterSelf(new JProperty("Department", "Personnel Department"));
Console.WriteLine(jObj.ToString());
//添加新的同事
JObject jObj = JObject.Parse(json);
JObject linda = new JObject(new JProperty("Name", "Linda"), new JProperty("Age", "23"));
jObj["Colleagues"].Last.AddAfterSelf(linda);
Console.WriteLine(jObj.ToString());
5,汇总
var cardJson = "['身份证','银行卡','门禁卡']";
var cardJArray = JArray.Parse(cardJson);
var p = new Person { Name="fan",Age=12,Dog=new Dog { Name="奶牛"} };
JObject jobj= JObject.FromObject(p);
//添加属性
jobj["NickName"] = "fan";
jobj["Wifes"] = new JArray("rose", "lisa");
((JArray)jobj["Wifes"]).Add( "july");
jobj["Cards"] = cardJArray;
//修改属性
jobj["Name"] = "li";
jobj["Age"] = 9;
jobj["Dog"]["Name"] = "阿黄";
((JArray)jobj["Wifes"])[0] = "roses";
//插入属性
jobj.Property("Name").AddBeforeSelf(new JProperty("ID", 1));
//删除属性
jobj.Property("Age").Remove();
((JArray)jobj["Wifes"])[2].Remove();
//查找
//遍历属性
var props = jobj.Children().Values();
foreach (var prop in props)
{
if (!(prop is JObject) && !(prop is JArray))
{
Console.WriteLine(prop.ToString());
}
}
//遍历数组
var cardList = ((JArray)jobj["Cards"]);
foreach (var card in cardList)
{
Console.WriteLine(card.ToString());
}
//强类型读取
Console.WriteLine(jobj.Value("ID"));
var p2 = jobj.ToString();
三,LINQ to Json各个类型的用法汇总
//JToken: 以下两种写法都可以被转换为 JToken 类型
string jtokenstring1 = "\"Hello World\"";
string jtokenstring2 = "{\"name\":\"John\",\"age\":30}";
JToken jtoken1 = JToken.Parse(jtokenstring1);
JToken jtoken2 = (JToken)JsonConvert.DeserializeObject(jtokenstring2);
//JObject: 只能序列化标准的 json 字符串
string jobjstring2 = "{\"name\":\"John\",\"age\":30}";
JObject jobj1 = JObject.Parse(jtokenstring2);
JObject jobj2 = (JObject)JsonConvert.DeserializeObject(jtokenstring2);
// JArray: 以下两种写法都可解析,主要标识是字符串的两端是中括号
string jarraystring1 = "[\"value1\",\"value2\"]";
string jarraystring2 = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Bob\",\"age\":20}]";
JArray jarray1 = JArray.Parse(jarraystring2);
JArray jarray2 = (JArray)JsonConvert.DeserializeObject(jarraystring2);
// 创建一个 JProperty 的对象,然后转成字符串值
string propertyname = "name";
string propertyvalue = "John";
JProperty jproperty = new JProperty(propertyname, propertyvalue);
var jp = jproperty.ToString();
// 输出结果:"name": "John"
// 但是通过这个输出的格式进行序列化时,就会提示异常,如下:
string jpropertystring1 = "\"name\": \"John\"";
// Newtonsoft.Json.JsonReaderException:Additional text encountered after finished reading JSON content
var jProperty1 = JProperty.Parse(jpropertystring1);
var jProperty2 = (JProperty)JsonConvert.DeserializeObject(jpropertystring1);
// 下面将 jproperty 对象加入 JObject
JObject jobject = new JObject(); // 将 JProperty 添加到 JObject 中
jobject.Add(jproperty);
string jsonstring = jobject.ToString(); // 将 JObject 转换为字符串
// 输出结果:{\r\n \"name\": \"John\"\r\n}
//JValue: 用法
JObject jsonObject = JObject.Parse("{\"a\":10,\"b\":\"Hello World\",\"c\":10}");
// 获取值信息
JValue jvaluea = (JValue)jsonObject["a"];
JValue jvalueb = (JValue)jsonObject["b"];
JValue jvaluec = (JValue)jsonObject["c"];
// JValue 两个实例比较
Console.WriteLine("jvaluea.Equals(jvalueb): " + jvaluea.Equals(jvalueb)); // false
Console.WriteLine("jvaluea.Equals(jvaluec): " + jvaluea.Equals(jvaluec)); // true
Console.WriteLine("jvaluea==jvaluec: " + (jvaluea == jvaluec)); // false
Console.WriteLine("jvalueb: " + jvalueb); // Hello World
int intValue = jvaluea.Value(); // 将值转换为整数类型
Console.WriteLine("Integer value: " + intValue);
四, Json格式的字符串转换为Json对象
// 以下是将字符串转成三种对象的方法,写法相同
JObject jo = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(strjson);
JToken jo = (JToken)Newtonsoft.Json.JsonConvert.DeserializeObject(strjson);
JArray jo = (JArray)Newtonsoft.Json.JsonConvert.DeserializeObject(strjson);
五,序列化和反序列化
序列化(Serialize)和反序列化(Deserialize)的定义:
- 序列化:把对象转化为可传输的字节序列过程称为序列化。
- 反序列化:把字节序列还原为对象的过程称为反序列化。
可见,序列化的目的是为了把对象进行网络传输和跨平台存储。跨平台存储和网络传输的方式就是网络和IO,而目前网络和IO支持的数据格式就是字节数组。白话文是:把数据存储到文件中,然后其他程序读取这个文件获取数据。
序列化是把C#对象转换为Json对象,而反序列化就是把Json对象转换为C#对象。
public class Product
{
string Name;
string Price decimal;
string [] Sizes;
}
Product product = new Product();
product.Name = "Apple";
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Price": 3.99,
// "Sizes": ["Small", "Medium", "Large"]
//}
Product deserializedProduct = JsonConvert.DeserializeObject(output)
摘抄文档,如有侵权,立马删除:
Newtonsoft.Json笔记 -JToken、JObject、JArray详解
Json 基于类 Newtonsoft.Json.Linq.JToken的应用简介