C# 解析Json文件(使用NewtonJson库)

C#中解析json文件有很多种方法,在多种方法中一般都会提到一个十分优秀的库:NewtonJson 。使用NewtonJson处理Json文件十分高效,而且在配置也十分简单,直接在Nuget包中导入即可。

目录

1.导入NewtonJson库

2.解析Json文件

2.1 最简单的序列化与反序列化

2.2 序列化集合和字典

2.3 反序列化集合和字典

2.4 将对象保存为Json文件&从文件解析为json

2.5 有条件的序列化对象成员

2.6 解析匿名类

2.7 将派生类解析为基类

2.8 防止重复写值

2.9 取消C#默认参数赋值& 过滤值为null的属性

2.10 类型缺少成员报错

3. 使用Linq处理json

3.1 解析Json的基本操作

3.2 修改Json(使用JObject)

3.3 合并Json文件

3.4 将Json类型转为普通类型

3.5 判断Json文件是否相等 &深度复制Json文件

4. 总结



1.导入NewtonJson库

编写C#程序肯定是在visual studio中写(暂不考虑unity等其他地方),那么无论你是在windows下还是Mac OS X下,visual studio都自带nuget包管理工具。本文以Mac OS X平台为例,首先新建一个项目叫ParseJson,然后在项目的依赖项中弹出快捷菜单,如下:

技术图片

点击Nuget包管理,弹出一个窗口:

技术图片

可以看到第一个就是我们想要的包,选中然后添加包即可。添加完成后在你的程序中添加下面两行:

  1.  
    using Newtonsoft.Json;

  2.  
    using Newtonsoft.Json.Linq;

至此,基本配置就完成了。


2.解析Json文件

NewtonJson官网有详细的使用文档教程,有很多示例代码,这里就不过多介绍了,遇到不懂的问题可以去文档里面找资料。

2.1 最简单的序列化与反序列化

假设你在C#中有一个定义好的类,然后你生成了一个对象,想把这个对象保存为Json文件,你可以用SerializeObject()函数处理。看下面的代码:

  1.  
    using System;

  2.  
    using System.IO;

  3.  
    using Newtonsoft.Json;

  4.  
    using Newtonsoft.Json.Linq;

  5.  
     
  6.  
    namespace ParseJson

  7.  
    {

  8.  
    class Product

  9.  
    {

  10.  
    public string Name;

  11.  
    public DateTime ExpiryDate;

  12.  
    public Decimal Price;

  13.  
    public String[] Sizes;

  14.  
    }

  15.  
     
  16.  
    class Program

  17.  
    {

  18.  
    static void Main(string[] args)

  19.  
    {

  20.  
    Product product =
    new Product()

  21.  
    {

  22.  
    Name =
    “Apple”,

  23.  
    ExpiryDate=
    new DateTime(2020,12,30),

  24.  
    Price=
    2.99M,

  25.  
    Sizes=
    new string[] {“small”,“medium”,“large”}

  26.  
     
  27.  
    };

  28.  
     
  29.  
    string output = JsonConvert.SerializeObject(product);

  30.  
     
  31.  
     
  32.  
    //将Json文件以字符串的形式保存

  33.  
    StreamWriter sw =
    new StreamWriter(@”/Users/qinyuanlong/Projects/SimpleTest/ParseJson/product.dat”);

  34.  
    sw.Write(output);

  35.  
    sw.Close();

  36.  
    Console.WriteLine(output);

  37.  
    }

  38.  
    }

  39.  
    }

这里我们创建了一个Product类,并且实例化了一个对象,利用JsonConvert.SerializeObject(product)将其转化为Json文件,并以字符串的形式存储在变量output,我们很容易将字符串保存到本地。可以查看保存到本地后的文件内容:

技术图片

既然我们可以将对象以json文件的形式保存,自然我们也应该可以从Json格式恢复成对象,做法很简单,假设我们已经读取了本地文件Product.dat,并保存到了字符串变量output中,我们要从中恢复成Product对象只需一句话:

  1.  
    //恢复对象

  2.  
    Product p = JsonConvert.DeserializeObject<Product>(output);

值得一提的的是,当你的对象里面有集合对象时:

  1.  
    public class Acount

  2.  
    {

  3.  
    public string Email {get;set;}

  4.  
    public Ilist<string> Roles {get;set}

  5.  
    }

也可以直接使用上面的方法,转化为Json文件后,集合对象会以数组的形式存储。


2.2 序列化集合和字典

除了序列化自定义的类,还可以将C#中的集合对象序列化,这里我就不跑代码了,直接搬运官网的例子。

序列化字典:

  1.  
    List<
    string> videogames = new List<string>

  2.  
    {

  3.  
    “Starcraft”,

  4.  
    “Halo”,

  5.  
    “Legend of Zelda”

  6.  
    };

  7.  
     
  8.  
    string json = JsonConvert.SerializeObject(videogames);

  9.  
     
  10.  
    Console.WriteLine(json);

  11.  
    // [“Starcraft”,”Halo”,”Legend of Zelda”]

List集合被转化为了数组,当然List里面可以是复杂的类型,如使用我们之前定义的Product:

  1.  
    Product product1 =
    new Product()

  2.  
    {

  3.  
    Name =
    “Apple”,

  4.  
    ExpiryDate=
    new DateTime(2020,12,30),

  5.  
    Price=
    2.99M,

  6.  
    Sizes=
    new string[] {“small”,“medium”,“large”}

  7.  
     
  8.  
    };

  9.  
    Product product2 =
    new Product()

  10.  
    {

  11.  
    Name =
    “cup”,

  12.  
    ExpiryDate =
    new DateTime(2099, 1, 1),

  13.  
    Price =
    9.99M,

  14.  
    Sizes =
    new string[] { “s”, “L”, “M”, “xL” }

  15.  
     
  16.  
    };

  17.  
     
  18.  
    List<Product> list =
    new List<Product>() { product1, product2 };

  19.  
    string json = JsonConvert.SerializeObject(list);

  20.  
    Console.WriteLine(json);

输出为:

[{"Name":"Apple","ExpiryDate":"2020-12-30T00:00:00","Price":2.99,"Sizes":["small","medium","large"]},{"Name":"cup","ExpiryDate":"2099-01-01T00:00:00","Price":9.99,"Sizes":["s","L","M","xL"]}]

序列化字典例子如下:

  1.  
    Dictionary<
    string, int> points = new Dictionary<string, int>

  2.  
    {

  3.  
    {
    “James”, 9001 },

  4.  
    {
    “Jo”, 3474 },

  5.  
    {
    “Jess”, 11926 }

  6.  
    };

  7.  
     
  8.  
    string json = JsonConvert.SerializeObject(points, Formatting.Indented);

  9.  
     
  10.  
    Console.WriteLine(json);

  11.  
    // {

  12.  
    // “James”: 9001,

  13.  
    // “Jo”: 3474,

  14.  
    // “Jess”: 11926

  15.  
    // }

这里SerializeObject多了一个参数,Indented表示转化为的Json文件带缩进,这样输出会更加直观清晰。

2.3 反序列化集合和字典

反序列化和之前讲的类似,反序列化需要给出转化为对象的类型,反序列化集合:

  1.  
    string json = @”[

  2.  
    {

  3.  
    ‘Name‘: ‘Product 1‘,

  4.  
    ‘ExpiryDate‘: ‘2000-12-29T00:00Z‘,

  5.  
    ‘Price‘: 99.95,

  6.  
    ‘Sizes‘: null

  7.  
    },

  8.  
    {

  9.  
    ‘Name‘: ‘Product 2‘,

  10.  
    ‘ExpiryDate‘: ‘2009-07-31T00:00Z‘,

  11.  
    ‘Price‘: 12.50,

  12.  
    ‘Sizes‘: null

  13.  
    }

  14.  
    ]”;

  15.  
     
  16.  
    List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);

  17.  
     
  18.  
    Console.WriteLine(products.Count);

  19.  
    // 2

  20.  
     
  21.  
    Product p1 = products[
    0];

  22.  
     
  23.  
    Console.WriteLine(p1.Name);

  24.  
    // Product 1

反序列化集合一般转为List类型,如果你需要转化为其它类型,你可以后续再处理。反序列化字典也是如此:

  1.  
    string json = @”{“”key1″”:””value1″”,””key2″”:””value2″”}”;

  2.  
     
  3.  
    Dictionary<
    string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

  4.  
     
  5.  
    Console.WriteLine(values.Count);

  6.  
    // 2

  7.  
     
  8.  
    Console.WriteLine(values[
    “key1”]);

  9.  
    // value1


2.4 将对象保存为Json文件&从文件解析为json

在最开始的例子中,我们将对象先转为字符串,然后再写入一个dat文件中,事实上完全可以将文件保存为Json文件。有两种思路,一种还是先将json变为字符串,然后保存到自定义的json文件中。

  1.  
    Product product1 =
    new Product()

  2.  
    {

  3.  
    Name =
    “Apple”,

  4.  
    ExpiryDate=
    new DateTime(2020,12,30),

  5.  
    Price=
    2.99M,

  6.  
    Sizes=
    new string[] {“small”,“medium”,“large”}

  7.  
     
  8.  
    };

  9.  
    Product product2 =
    new Product()

  10.  
    {

  11.  
    Name =
    “cup”,

  12.  
    ExpiryDate =
    new DateTime(2099, 1, 1),

  13.  
    Price =
    9.99M,

  14.  
    Sizes =
    new string[] { “s”, “L”, “M”, “xL” }

  15.  
     
  16.  
    };

  17.  
     
  18.  
    List<Product> list =
    new List<Product>() { product1, product2 };

  19.  
    File.WriteAllText(
    @”/Users/qinyuanlong/Projects/SimpleTest/ParseJson/product1.json”,

  20.  
    JsonConvert.SerializeObject(list,Formatting.Indented));

我们用Vscode打开product1.json如下:

技术图片

另一种方法是直接将对象转化为json文件:

  1.  
    using(StreamWriterfile=File.CreateText(@”/Users/qinyuanlong/Projects/SimpleTest/ParseJson/product2.json”))

  2.  
    {

  3.  
    JsonSerializer serializer =
    new JsonSerializer() { Formatting=Formatting.Indented};

  4.  
     
  5.  
    serializer.Serialize(file, list);

  6.  
    }

得到的product2.json和前面是一样的。

从json文件中解析对象的操作几乎是一模一样的:只需要将SerializeObject函数换成DeserializeObject,WriteAllText换成ReadAllText,CreatText换成OpenText。

  1.  
    // read file into a string and deserialize JSON to a type

  2.  
    Movie movie1 = JsonConvert.DeserializeObject<Movie>(File.ReadAllText(
    @”c:\movie.json”));

  3.  
     
  4.  
    // deserialize JSON directly from a file

  5.  
    using (StreamReader file = File.OpenText(@”c:\movie.json”))

  6.  
    {

  7.  
    JsonSerializer serializer =
    new JsonSerializer();

  8.  
    Movie movie2 = (Movie)serializer.Deserialize(file,
    typeof(Movie));

  9.  
    }

 注意:直接从json转为对象,除了提供对象类型参数,还需要强制转化操作。


2.5 有条件的序列化对象成员

NewTonJson还支持有条件序列化对象,即对某些属性进行判断,如果不满足要求,则忽略该属性。

要实现部分属性的条件序列化,需要添加一些函数,这个函数和属性一一对应,函数名为:ShouldSerialize+属性名,函数的返回值为bool类型,当返回为True时,该属性将被序列化,为False则被忽略。看一个官方例子:

首先你有这样一个简单类:

  1.  
    public class Employee

  2.  
    {

  3.  
    public string Name { get; set; }

  4.  
    public Employee Manager { get; set; }

  5.  
     
  6.  
    public bool ShouldSerializeManager()

  7.  
    {

  8.  
    // don‘t serialize the Manager property if an employee is their own manager

  9.  
    return (Manager != this);

  10.  
    }

  11.  
    }

这里已经添加了Manager这个筛选函数,所以当Manage就是自己时,这个Manage会被忽略。

  1.  
    Employee joe =
    new Employee();

  2.  
    joe.Name =
    “Joe Employee”;

  3.  
    Employee mike =
    new Employee();

  4.  
    mike.Name =
    “Mike Manager”;

  5.  
     
  6.  
    joe.Manager = mike;

  7.  
     
  8.  
    // mike is his own manager

  9.  
    // ShouldSerialize will skip this property

  10.  
    mike.Manager = mike;

  11.  
     
  12.  
    string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented);

  13.  
     
  14.  
    Console.WriteLine(json);

  15.  
    // [

  16.  
    // {

  17.  
    // “Name”: “Joe Employee”,

  18.  
    // “Manager”: {

  19.  
    // “Name”: “Mike Manager”

  20.  
    // }

  21.  
    // },

  22.  
    // {

  23.  
    // “Name”: “Mike Manager”

  24.  
    // }

  25.  
    // ]

不过一般而言,当数据量不是很大时,你可以有条件的使用Json文件的数据,也就是我不用这个属性,我就可以假设它不存在。

上面的例子固然可行,但是有个很麻烦的问题:你必须在设计类的时候就确定好条件序列化属性。

那么有没有更好的控制办法呢?答案是肯定的。

通过派生接口:IContractResolver,生产一个筛选对象可以实现定制化筛选,你不用在你的类里面添加函数。一般我们不用直接派生自IContractResolver,而是派生自它的一个派生类:

DefaultContractResolver

看下面这个例子,我们假设有这样一个图书类:

  1.  
    public class Book

  2.  
    {

  3.  
    public string BookName { get; set; }

  4.  
    public decimal BookPrice { get; set; }

  5.  
    public string AuthorName { get; set; }

  6.  
    public int AuthorAge { get; set; }

  7.  
    public string AuthorCountry { get; set; }

  8.  
    }

我们想实现序列化以字母“A”开头或者“B”开头的属性,显然用之前的方法会很麻烦,我们用刚才的方法,派生一个筛选类:

  1.  
    public class DynamicContractResolver : DefaultContractResolver

  2.  
    {

  3.  
    private readonly char _startingWithChar;

  4.  
     
  5.  
    public DynamicContractResolver(char startingWithChar)

  6.  
    {

  7.  
    _startingWithChar = startingWithChar;

  8.  
    }

  9.  
     
  10.  
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)

  11.  
    {

  12.  
    IList<JsonProperty> properties =
    base.CreateProperties(type, memberSerialization);

  13.  
     
  14.  
    // only serializer properties that start with the specified character

  15.  
    //只需要在这里添加属性筛选

  16.  
    properties =

  17.  
    properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();

  18.  
     
  19.  
    return properties;

  20.  
    }

  21.  
    }

这个类有一个成员变量:_startingWithChar,用来接受筛选参数;一个构造函数;一个筛选函数:CreateProperties,这个函数返回一个属性集合,函数首先获得类的所有属性,保存带properties中,然后你根据需求对properties进行处理。上面的函数实现了根据属性名的首字母进行筛选。所以我们就可以用这个类的对象作为参数去实现我们的需求:

  1.  
    Book book =
    new Book

  2.  
    {

  3.  
    BookName =
    “The Gathering Storm”,

  4.  
    BookPrice =
    16.19m,

  5.  
    AuthorName =
    “Brandon Sanderson”,

  6.  
    AuthorAge =
    34,

  7.  
    AuthorCountry =
    “United States of America”

  8.  
    };

  9.  
     
  10.  
    string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented,

  11.  
    new JsonSerializerSettings { ContractResolver = new DynamicContractResolver(‘A‘) });

  12.  
     
  13.  
    // {

  14.  
    // “AuthorName”: “Brandon Sanderson”,

  15.  
    // “AuthorAge”: 34,

  16.  
    // “AuthorCountry”: “United States of America”

  17.  
    // }

  18.  
     
  19.  
    string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented,

  20.  
    new JsonSerializerSettings { ContractResolver = new DynamicContractResolver(‘B‘) });

  21.  
     
  22.  
    // {

  23.  
    // “BookName”: “The Gathering Storm”,

  24.  
    // “BookPrice”: 16.19

  25.  
    // }

DefaultContractResolver中的CreateProperties是对多个属性筛选而言的,回到本节最开始的问题,我只想对Manage成员进行筛选,那么可以用CreateProperty这个函数,具体用法如下:

  1.  
    public class ShouldSerializeContractResolver : DefaultContractResolver

  2.  
    {

  3.  
    public static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();

  4.  
     
  5.  
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)

  6.  
    {

  7.  
    JsonProperty property =
    base.CreateProperty(member, memberSerialization);

  8.  
     
  9.  
    if (property.DeclaringType == typeof(Employee) && property.PropertyName == “Manager”)

  10.  
    {

  11.  
    property.ShouldSerialize =

  12.  
    instance =>

  13.  
    {

  14.  
    Employee e = (Employee)instance;

  15.  
    return e.Manager != e;

  16.  
    };

  17.  
    }

  18.  
     
  19.  
    return property;

  20.  
    }

  21.  
    }

这个的用法和前面类似,不过这里直接声明了一个类的静态成员,所以不需要new一个对象:

  1.  
    string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented,

  2.  
    new JsonSerializerSettings { ContractResolver=ShouldSerializeContractResolver.Instance});

顺便要说明的是,为了成功运行需要添加新的命名空间:

  1.  
    using Newtonsoft.Json.Linq;

  2.  
    using Newtonsoft.Json.Serialization;

这里给出官网关于DefaultContrctResolver的链接


2.6 解析匿名类

对于匿名类,由于序列化不需要给出对象类型,所以可以依然使用前面序列化自定义类的方法,但是反序列是需要提供类型的,那对于匿名类怎么办?,这个NewtonJson也替我们考虑了,例子如下:

  1.  
    var definition = new { Name = “” };

  2.  
     
  3.  
    string json1 = @”{‘Name‘:‘James‘}”;

  4.  
    var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);

  5.  
     
  6.  
    Console.WriteLine(customer1.Name);

  7.  
    // James

  8.  
     
  9.  
    string json2 = @”{‘Name‘:‘Mike‘}”;

  10.  
    var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);

  11.  
     
  12.  
    Console.WriteLine(customer2.Name);

  13.  
    // Mike

办法很简单,直接给一个匿名类的定义对象,传入参数即可。

2.7 将派生类解析为基类

将派生类解析为基类,需要一个派生自CustomeCreationConverter的对象,操作起来其实很简单,看一下官方的例子:

首先你有一个Person基类,然后派生了Employee类,并写好了派生自CustomeCreationConverter类的类PersonConverter:

  1.  
    public class Person

  2.  
    {

  3.  
    public string FirstName { get; set; }

  4.  
    public string LastName { get; set; }

  5.  
    public DateTime BirthDate { get; set; }

  6.  
    }

  7.  
     
  8.  
    public class Employee : Person

  9.  
    {

  10.  
    public string Department { get; set; }

  11.  
    public string JobTitle { get; set; }

  12.  
    }

  13.  
     
  14.  
    public class PersonConverter : CustomCreationConverter<Person>

  15.  
    {

  16.  
    public override Person Create(Type objectType)

  17.  
    {

  18.  
    return new Employee();

  19.  
    }

  20.  
    }

然后你想将Employee对象解析为Person,只需要传入一个PersonConvrter对象:

  1.  
    string json = @”{

  2.  
    ‘Department‘: ‘Furniture‘,

  3.  
    ‘JobTitle‘: ‘Carpenter‘,

  4.  
    ‘FirstName‘: ‘John‘,

  5.  
    ‘LastName‘: ‘Joinery‘,

  6.  
    ‘BirthDate‘: ‘1983-02-02T00:00:00‘

  7.  
    }”;

  8.  
     
  9.  
    Person person = JsonConvert.DeserializeObject<Person>(json,
    new PersonConverter());

  10.  
     
  11.  
    Console.WriteLine(person.GetType().Name);

  12.  
    // Employee

  13.  
     
  14.  
    Employee employee = (Employee)person;

  15.  
     
  16.  
    Console.WriteLine(employee.JobTitle);

  17.  
    // Carpenter

从结果可以看出,虽然是以Person解析的,但是实际上仍然是Employee类型。


2.8 防止重复写值

如果一个类的构造函数本身就对成员进行了赋值,那么在反序列化时,可能会调用一次构造函数容易造成重复写入,看下面的例子:

  1.  
    public class UserViewModel

  2.  
    {

  3.  
    public string Name { get; set; }

  4.  
    public IList<string> Offices { get; private set; }

  5.  
     
  6.  
    public UserViewModel()

  7.  
    {

  8.  
    Offices =
    new List<string>

  9.  
    {

  10.  
    “Auckland”,

  11.  
    “Wellington”,

  12.  
    “Christchurch”

  13.  
    };

  14.  
    }

  15.  
    }

构造函数对成员Offices进行了赋值:

  1.  
    string json = @”{

  2.  
    ‘Name‘: ‘James‘,

  3.  
    ‘Offices‘: [

  4.  
    ‘Auckland‘,

  5.  
    ‘Wellington‘,

  6.  
    ‘Christchurch‘

  7.  
    ]

  8.  
    }”;

  9.  
     
  10.  
    UserViewModel model1 = JsonConvert.DeserializeObject<UserViewModel>(json);

  11.  
     
  12.  
    foreach (string office in model1.Offices)

  13.  
    {

  14.  
    Console.WriteLine(office);

  15.  
    }

  16.  
    // Auckland

  17.  
    // Wellington

  18.  
    // Christchurch

  19.  
    // Auckland

  20.  
    // Wellington

  21.  
    // Christchurch

  22.  
     
  23.  
    UserViewModel model2 = JsonConvert.DeserializeObject<UserViewModel>(json,
    new JsonSerializerSettings

  24.  
    {

  25.  
    ObjectCreationHandling = ObjectCreationHandling.Replace

  26.  
    });

  27.  
     
  28.  
    foreach (string office in model2.Offices)

  29.  
    {

  30.  
    Console.WriteLine(office);

  31.  
    }

  32.  
    // Auckland

  33.  
    // Wellington

  34.  
    // Christchurch

如果不添加设定,Offices就是存在2遍初始值,为例避免这种情况,在反序列化的时候传入了一个setting对象,其ObejctCreationHandling属性为Replcae。


2.9 取消C#默认参数赋值& 过滤值为null的属性

C#对于没有赋值的类型提供一个默认值,如Int类型默认值为0,string类型默认值为null,如果当一个对象的成员没有被赋值,我们希望得到的是一个空json,那么需要将setting的DefaultValueHandleling设置为Ignore。

  1.  
    public class Person

  2.  
    {

  3.  
    public string Name { get; set; }

  4.  
    public int Age { get; set; }

  5.  
    public Person Partner { get; set; }

  6.  
    public decimal? Salary { get; set; }

  7.  
    }

  8.  
     
  9.  
    Person person =
    new Person();

  10.  
     
  11.  
    string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented);

  12.  
     
  13.  
    Console.WriteLine(jsonIncludeDefaultValues);

  14.  
    // {

  15.  
    // “Name”: null,

  16.  
    // “Age”: 0,

  17.  
    // “Partner”: null,

  18.  
    // “Salary”: null

  19.  
    // }

  20.  
     
  21.  
    string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings

  22.  
    {

  23.  
    DefaultValueHandling = DefaultValueHandling.Ignore

  24.  
    });

  25.  
     
  26.  
    Console.WriteLine(jsonIgnoreDefaultValues);

  27.  
    // {}

过滤值为null的成员只需要将NullValueHandling属性设置为Ignore。 

  1.  
    public class Person

  2.  
    {

  3.  
    public string Name { get; set; }

  4.  
    public int Age { get; set; }

  5.  
    public Person Partner { get; set; }

  6.  
    public decimal? Salary { get; set; }

  7.  
    }

  8.  
     
  9.  
    Person person =
    new Person

  10.  
    {

  11.  
    Name =
    “Nigal Newborn”,

  12.  
    Age =
    1

  13.  
    };

  14.  
     
  15.  
    string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented);

  16.  
     
  17.  
    Console.WriteLine(jsonIncludeNullValues);

  18.  
    // {

  19.  
    // “Name”: “Nigal Newborn”,

  20.  
    // “Age”: 1,

  21.  
    // “Partner”: null,

  22.  
    // “Salary”: null

  23.  
    // }

  24.  
     
  25.  
    string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings

  26.  
    {

  27.  
    NullValueHandling = NullValueHandling.Ignore

  28.  
    });

  29.  
     
  30.  
    Console.WriteLine(jsonIgnoreNullValues);

  31.  
    // {

  32.  
    // “Name”: “Nigal Newborn”,

  33.  
    // “Age”: 1

  34.  
    // }


2.10 类型缺少成员报错

当我们将下面的json文件:

  1.  
    string json = @”{

  2.  
    ‘FullName‘: ‘Dan Deleted‘,

  3.  
    ‘Deleted‘: true,

  4.  
    ‘DeletedDate‘: ‘2013-01-20T00:00:00‘

  5.  
    }”;

解析为Account类型时:

  1.  
    public class Account

  2.  
    {

  3.  
    public string FullName { get; set; }

  4.  
    public bool Deleted { get; set; }

  5.  
    }

是可以成功的,因为json中包含Accout类中所有成员属性。但是如果我们要严格转化(特别是在Accout漏掉属性时),需要报错,那么就需要设置setting的MissingMemberHandling属性。

  1.  
    try

  2.  
    {

  3.  
    JsonConvert.DeserializeObject<Account>(json,
    new JsonSerializerSettings

  4.  
    {

  5.  
    MissingMemberHandling = MissingMemberHandling.Error

  6.  
    });

  7.  
    }

  8.  
    catch (JsonSerializationException ex)

  9.  
    {

  10.  
    Console.WriteLine(ex.Message);

  11.  
    // Could not find member ‘DeletedDate‘ on object of type ‘Account‘. Path ‘DeletedDate‘, line 4, position 23.

  12.  
    }

此外还有很多设置用来解决各种问题,上面只是列出了一些常见的,有需要的还是要去官网查看。


3. 使用Linq处理json

使用ling处理json最大的好处是摆脱了对象的束缚,使用NewtonJson自带的一套体系。我们都知道JavaScript原生支持Json,直接可以将Json文件转化为一个对象,JObject的创建也是为了实现这样一个类似的功能。

3.1 解析Json的基本操作

  • 解析文本为Json对象
    直接使用JObject.Parse(obj)即可
    1.  
      string json = @”{

    2.  
      CPU: ‘Intel‘,

    3.  
      Drives: [

    4.  
      ‘DVD read/writer‘,

    5.  
      ‘500 gigabyte hard drive‘

    6.  
      ]

    7.  
      }”;

    8.  
       
    9.  
      JObject o = JObject.Parse(json);

    10.  
      Console.WriteLine(o.ToString());

    11.  
      // {

    12.  
      // “CPU”: “Intel”,

    13.  
      // “Drives”: [

    14.  
      // “DVD read/writer”,

    15.  
      // “500 gigabyte hard drive”

    16.  
      // ]

    17.  
      // }

     

  • 将数组解析为Json
    直接使用JArray类
    1.  
      string json = @”[

    2.  
      ‘Small‘,

    3.  
      ‘Medium‘,

    4.  
      ‘Large‘

    5.  
      ]”;

    6.  
       
    7.  
      JArray a = JArray.Parse(json);

    8.  
       
    9.  
      Console.WriteLine(a.Tostring());

    10.  
      // [

    11.  
      // “Small”,

    12.  
      // “Medium”,

    13.  
      // “Large”

    14.  
      // ]

     

  • 从本地Json文件中解析 
    读操作

    1.  
      using (StreamReader reader = File.OpenText(@”c:\person.json”))

    2.  
      {

    3.  
      JObject o = (JObject)JToken.ReadFrom(
      new JsonTextReader(reader));

    4.  
      // do stuff

    5.  
      }

    写操作
     

    1.  
      JObject videogameRatings =
      new JObject(

    2.  
      new JProperty(“Halo”, 9),

    3.  
      new JProperty(“Starcraft”, 9),

    4.  
      new JProperty(“Call of Duty”, 7.5));

    5.  
       
    6.  
      File.WriteAllText(
      @”c:\videogames.json”, videogameRatings.ToString());

    7.  
       
    8.  
      // write JSON directly to a file

    9.  
      using (StreamWriter file = File.CreateText(@”c:\videogames.json”))

    10.  
      using (JsonTextWriter writer = new JsonTextWriter(file))

    11.  
      {

    12.  
      videogameRatings.WriteTo(writer);

    13.  
      }

     

  • 创建JObject对象,JArray对象
    1.  
      JArray array =
      new JArray();

    2.  
      array.Add(
      “Manual text”);

    3.  
      array.Add(
      new DateTime(2000, 5, 23));

    4.  
       
    5.  
      JObject o =
      new JObject();

    6.  
      o[
      “MyArray”] = array;

    7.  
       
    8.  
      string json = o.ToString();

    9.  
      // {

    10.  
      // “MyArray”: [

    11.  
      // “Manual text”,

    12.  
      // “2000-05-23T00:00:00”

    13.  
      // ]

    14.  
      // }

  • 使用C#中的集合初始化语法创建复杂对象
    可以直接使用C#的初始化语法创建嵌套类型
     
    1.  
      JObject o =
      new JObject

    2.  
      {

    3.  
      {
      “Cpu”, “Intel” },

    4.  
      {
      “Memory”, 32 },

    5.  
      {

    6.  
      “Drives”, new JArray

    7.  
      {

    8.  
      “DVD”,

    9.  
      “SSD”

    10.  
      }

    11.  
      }

    12.  
      };

    13.  
       
    14.  
      Console.WriteLine(o.ToString());

    15.  
      // {

    16.  
      // “Cpu”: “Intel”,

    17.  
      // “Memory”: 32,

    18.  
      // “Drives”: [

    19.  
      // “DVD”,

    20.  
      // “SSD”

    21.  
      // ]

    22.  
      // }

    当然也可以用传统的对象创建方法,但是会觉得繁琐,看下面的例子:
     

    1.  
      public class Post

    2.  
      {

    3.  
      public string Title { get; set; }

    4.  
      public string Description { get; set; }

    5.  
      public string Link { get; set; }

    6.  
      public IList<string> Categories { get; set; }

    7.  
      }

    8.  
      List<Post> posts = GetPosts();

    9.  
       
    10.  
      JObject rss =

    11.  
      new JObject(

    12.  
      new JProperty(“channel”,

    13.  
      new JObject(

    14.  
      new JProperty(“title”, “James Newton-King”),

    15.  
      new JProperty(“link”, “http://james.newtonking.com”),

    16.  
      new JProperty(“description”, “James Newton-King‘s blog.”),

    17.  
      new JProperty(“item”,

    18.  
      new JArray(

    19.  
      from p in posts

    20.  
      orderby p.Title

    21.  
      select new JObject(

    22.  
      new JProperty(“title”, p.Title),

    23.  
      new JProperty(“description”, p.Description),

    24.  
      new JProperty(“link”, p.Link),

    25.  
      new JProperty(“category”,

    26.  
      new JArray(

    27.  
      from c in p.Categories

    28.  
      select new JValue(c)))))))));

    29.  
       
    30.  
      Console.WriteLine(rss.ToString());

    31.  
       
    32.  
      // {

    33.  
      // “channel”: {

    34.  
      // “title”: “James Newton-King”,

    35.  
      // “link”: “http://james.newtonking.com”,

    36.  
      // “description”: “James Newton-King‘s blog.”,

    37.  
      // “item”: [

    38.  
      // {

    39.  
      // “title”: “Json.NET 1.3 + New license + Now on CodePlex”,

    40.  
      // “description”: “Announcing the release of Json.NET 1.3, the MIT license and being available on CodePlex”,

    41.  
      // “link”: “http://james.newtonking.com/projects/json-net.aspx”,

    42.  
      // “category”: [

    43.  
      // “Json.NET”,

    44.  
      // “CodePlex”

    45.  
      // ]

    46.  
      // },

    47.  
      // {

    48.  
      // “title”: “LINQ to JSON beta”,

    49.  
      // “description”: “Announcing LINQ to JSON”,

    50.  
      // “link”: “http://james.newtonking.com/projects/json-net.aspx”,

    51.  
      // “category”: [

    52.  
      // “Json.NET”,

    53.  
      // “LINQ”

    54.  
      // ]

    55.  
      // }

    56.  
      // ]

    57.  
      // }

    58.  
      // }

     

  • 动态创建JObject和JArray对象
    使用C#的动态类型,可以动态的创建JObject和JArray对象
    1.  
      dynamic product = new JObject();

    2.  
      product.ProductName =
      “Elbow Grease”;

    3.  
      product.Enabled =
      true;

    4.  
      product.Price =
      4.90m;

    5.  
      product.StockCount =
      9000;

    6.  
      product.StockValue =
      44100;

    7.  
      product.Tags =
      new JArray(“Real”, “OnSale”);

    8.  
       
    9.  
      Console.WriteLine(product.ToString());

    10.  
      // {

    11.  
      // “ProductName”: “Elbow Grease”,

    12.  
      // “Enabled”: true,

    13.  
      // “Price”: 4.90,

    14.  
      // “StockCount”: 9000,

    15.  
      // “StockValue”: 44100,

    16.  
      // “Tags”: [

    17.  
      // “Real”,

    18.  
      // “OnSale”

    19.  
      // ]

    20.  
      // }

     

  • 使用JTokenWriter动态创建JObject对象
    JTokenWriter类有一套完整的节点写入方法,详细文档在此,在写入的过程,有点像在JS中添加Dom元素。
    1.  
      JTokenWriter writer =
      new JTokenWriter();

    2.  
      writer.WriteStartObject();

    3.  
      writer.WritePropertyName(
      “name1”);

    4.  
      writer.WriteValue(
      “value1”);

    5.  
      writer.WritePropertyName(
      “name2”);

    6.  
      writer.WriteStartArray();

    7.  
      writer.WriteValue(
      1);

    8.  
      writer.WriteValue(
      2);

    9.  
      writer.WriteEndArray();

    10.  
      writer.WriteEndObject();

    11.  
       
    12.  
      JObject o = (JObject)writer.Token;

    13.  
       
    14.  
      Console.WriteLine(o.ToString());

    15.  
      // {

    16.  
      // “name1”: “value1”,

    17.  
      // “name2”: [

    18.  
      // 1,

    19.  
      // 2

    20.  
      // ]

    21.  
      // }

     

  • 从自定义对象生成JObject对象 
    使用FromObject函数可以从自定义的类中生产JObject对象,用法如下:
    1.  
      public class Computer

    2.  
      {

    3.  
      public string Cpu { get; set; }

    4.  
      public int Memory { get; set; }

    5.  
      public IList<string> Drives { get; set; }

    6.  
      }

    7.  
       
    8.  
      JValue i = (JValue)JToken.FromObject(
      12345);

    9.  
       
    10.  
      Console.WriteLine(i.Type);

    11.  
      // Integer

    12.  
      Console.WriteLine(i.ToString());

    13.  
      // 12345

    14.  
       
    15.  
      JValue s = (JValue)JToken.FromObject(
      “A string”);

    16.  
       
    17.  
      Console.WriteLine(s.Type);

    18.  
      // String

    19.  
      Console.WriteLine(s.ToString());

    20.  
      // A string

    21.  
       
    22.  
      Computer computer =
      new Computer

    23.  
      {

    24.  
      Cpu =
      “Intel”,

    25.  
      Memory =
      32,

    26.  
      Drives =
      new List<string>

    27.  
      {

    28.  
      “DVD”,

    29.  
      “SSD”

    30.  
      }

    31.  
      };

    32.  
       
    33.  
      JObject o = (JObject)JToken.FromObject(computer);

    34.  
       
    35.  
      Console.WriteLine(o.ToString());

    36.  
      // {

    37.  
      // “Cpu”: “Intel”,

    38.  
      // “Memory”: 32,

    39.  
      // “Drives”: [

    40.  
      // “DVD”,

    41.  
      // “SSD”

    42.  
      // ]

    43.  
      // }

    44.  
       
    45.  
      JArray a = (JArray)JToken.FromObject(computer.Drives);

    46.  
       
    47.  
      Console.WriteLine(a.ToString());

    48.  
      // [

    49.  
      // “DVD”,

    50.  
      // “SSD”

    51.  
      // ]

    这个函数还可以直接从匿名对象创建:
     

    1.  
      List<Post> posts =
      new List<Post>

    2.  
      {

    3.  
      new Post

    4.  
      {

    5.  
      Title =
      “Episode VII”,

    6.  
      Description =
      “Episode VII production”,

    7.  
      Categories =
      new List<string>

    8.  
      {

    9.  
      “episode-vii”,

    10.  
      “movie”

    11.  
      },

    12.  
      Link =
      “episode-vii-production.aspx”

    13.  
      }

    14.  
      };

    15.  
       
    16.  
      JObject o = JObject.FromObject(
      new

    17.  
      {

    18.  
      channel =
      new

    19.  
      {

    20.  
      title =
      “Star Wars”,

    21.  
      link =
      “http://www.starwars.com”,

    22.  
      description =
      “Star Wars blog.”,

    23.  
      item =

    24.  
      from p in posts

    25.  
      orderby p.Title

    26.  
      select new

    27.  
      {

    28.  
      title = p.Title,

    29.  
      description = p.Description,

    30.  
      link = p.Link,

    31.  
      category = p.Categories

    32.  
      }

    33.  
      }

    34.  
      });

    35.  
       
    36.  
      Console.WriteLine(o.ToString());

    37.  
      // {

    38.  
      // “channel”: {

    39.  
      // “title”: “Star Wars”,

    40.  
      // “link”: “http://www.starwars.com”,

    41.  
      // “description”: “Star Wars blog.”,

    42.  
      // “item”: [

    43.  
      // {

    44.  
      // “title”: “Episode VII”,

    45.  
      // “description”: “Episode VII production”,

    46.  
      // “link”: “episode-vii-production.aspx”,

    47.  
      // “category”: [

    48.  
      // “episode-vii”,

    49.  
      // “movie”

    50.  
      // ]

    51.  
      // }

    52.  
      // ]

    53.  
      // }

    54.  
      // }

     

从JObject恢复出类对象
这个实际上没有什么技巧,只是写一个动态创建函数:

  1.  
    public class BlogPost

  2.  
    {

  3.  
    public string Title { get; set; }

  4.  
    public string AuthorName { get; set; }

  5.  
    public string AuthorTwitter { get; set; }

  6.  
    public string Body { get; set; }

  7.  
    public DateTime PostedDate { get; set; }

  8.  
    }

  9.  
    string json = @”[

  10.  
    {

  11.  
    ‘Title‘: ‘Json.NET is awesome!‘,

  12.  
    ‘Author‘: {

  13.  
    ‘Name‘: ‘James Newton-King‘,

  14.  
    ‘Twitter‘: ‘@JamesNK‘,

  15.  
    ‘Picture‘: ‘/jamesnk.png‘

  16.  
    },

  17.  
    ‘Date‘: ‘2013-01-23T19:30:00‘,

  18.  
    ‘BodyHtml‘: ‘&lt;h3&gt;Title!&lt;/h3&gt;\r\n&lt;p&gt;Content!&lt;/p&gt;‘

  19.  
    }

  20.  
    ]”;

  21.  
     
  22.  
    JArray blogPostArray = JArray.Parse(json);

  23.  
     
  24.  
    IList<BlogPost> blogPosts = blogPostArray.Select(p =>
    new BlogPost

  25.  
    {

  26.  
    Title = (
    string)p[“Title”],

  27.  
    AuthorName = (
    string)p[“Author”][“Name”],

  28.  
    AuthorTwitter = (
    string)p[“Author”][“Twitter”],

  29.  
    PostedDate = (DateTime)p[
    “Date”],

  30.  
    Body = HttpUtility.HtmlDecode((
    string)p[“BodyHtml”])

  31.  
    }).ToList();

  32.  
     
  33.  
    Console.WriteLine(blogPosts[
    0].Body);

  34.  
    // <h3>Title!</h3>

  35.  
    // <p>Content!</p>

 那么反过来,也可以用这个方法将对象变为Jobject对象:

  1.  
    IList<BlogPost> blogPosts =
    new List<BlogPost>

  2.  
    {

  3.  
    new BlogPost

  4.  
    {

  5.  
    Title =
    “Json.NET is awesome!”,

  6.  
    AuthorName =
    “James Newton-King”,

  7.  
    AuthorTwitter =
    “JamesNK”,

  8.  
    PostedDate =
    new DateTime(2013, 1, 23, 19, 30, 0),

  9.  
    Body =
    @”<h3>Title!</h3><p>Content!</p>”

  10.  
    }

  11.  
    };

  12.  
     
  13.  
    JArray blogPostsArray =
    new JArray(

  14.  
    blogPosts.Select(p =>
    new JObject

  15.  
    {

  16.  
    {
    “Title”, p.Title },

  17.  
    {

  18.  
    “Author”, new JObject

  19.  
    {

  20.  
    {
    “Name”, p.AuthorName },

  21.  
    {
    “Twitter”, p.AuthorTwitter }

  22.  
    }

  23.  
    },

  24.  
    {
    “Date”, p.PostedDate },

  25.  
    {
    “BodyHtml”, HttpUtility.HtmlEncode(p.Body) },

  26.  
    })

  27.  
    );

  28.  
     
  29.  
    Console.WriteLine(blogPostsArray.ToString());

  30.  
    // [

  31.  
    // {

  32.  
    // “Title”: “Json.NET is awesome!”,

  33.  
    // “Author”: {

  34.  
    // “Name”: “James Newton-King”,

  35.  
    // “Twitter”: “JamesNK”

  36.  
    // },

  37.  
    // “Date”: “2013-01-23T19:30:00”,

  38.  
    // “BodyHtml”: “&lt;h3&gt;Title!&lt;/h3&gt;&lt;p&gt;Content!&lt;/p&gt;”

  39.  
    // }

  40.  
    // ]


3.2 修改Json(使用JObject)

JObject对象很容易修改Json文件,修改包括增,删,重写,等操作。

  1.  
    string json = @”{

  2.  
    ‘channel‘: {

  3.  
    ‘title‘: ‘Star Wars‘,

  4.  
    ‘link‘: ‘http://www.starwars.com‘,

  5.  
    ‘description‘: ‘Star Wars blog.‘,

  6.  
    ‘obsolete‘: ‘Obsolete value‘,

  7.  
    ‘item‘: []

  8.  
    }

  9.  
    }”;

  10.  
     
  11.  
    JObject rss = JObject.Parse(json);

  12.  
     
  13.  
    JObject channel = (JObject)rss[
    “channel”];

  14.  
     
  15.  
    channel[
    “title”] = ((string)channel[“title”]).ToUpper();

  16.  
    channel[
    “description”] = ((string)channel[“description”]).ToUpper();

  17.  
     
  18.  
    channel.Property(
    “obsolete”).Remove();

  19.  
     
  20.  
    channel.Property(
    “description”).AddAfterSelf(new JProperty(“new”, “New value”));

  21.  
     
  22.  
    JArray item = (JArray)channel[
    “item”];

  23.  
    item.Add(
    “Item 1”);

  24.  
    item.Add(
    “Item 2”);

  25.  
     
  26.  
    Console.WriteLine(rss.ToString());

  27.  
    // {

  28.  
    // “channel”: {

  29.  
    // “title”: “STAR WARS”,

  30.  
    // “link”: “http://www.starwars.com”,

  31.  
    // “description”: “STAR WARS BLOG.”,

  32.  
    // “new”: “New value”,

  33.  
    // “item”: [

  34.  
    // “Item 1”,

  35.  
    // “Item 2”

  36.  
    // ]

  37.  
    // }

  38.  
    // }

在上面的例子,依次进行了:使用函数修改值,删除属性,在某属性后面添加属性,在数组内部添加成员。


3.3 合并Json文件

合并Json文件也很简单,类似于两个集合的操作,看下面的例子:

  1.  
    JObject o1 = JObject.Parse(
    @”{

  2.  
    ‘FirstName‘: ‘John‘,

  3.  
    ‘LastName‘: ‘Smith‘,

  4.  
    ‘Enabled‘: false,

  5.  
    ‘Roles‘: [ ‘User‘ ]

  6.  
    }”);

  7.  
    JObject o2 = JObject.Parse(
    @”{

  8.  
    ‘Enabled‘: true,

  9.  
    ‘Roles‘: [ ‘User‘, ‘Admin‘ ]

  10.  
    }”);

  11.  
     
  12.  
    o1.Merge(o2,
    new JsonMergeSettings

  13.  
    {

  14.  
    // union array values together to avoid duplicates

  15.  
    MergeArrayHandling = MergeArrayHandling.Union

  16.  
    });

  17.  
     
  18.  
    string json = o1.ToString();

  19.  
    // {

  20.  
    // “FirstName”: “John”,

  21.  
    // “LastName”: “Smith”,

  22.  
    // “Enabled”: true,

  23.  
    // “Roles”: [

  24.  
    // “User”,

  25.  
    // “Admin”

  26.  
    // ]

  27.  
    // }

这里要说的是,可以使用MergeArrayHandling对象来设置合并方式,上面使用的是合并模式:Union,即当前Json有时,只会出现一次,此外还有:

技术图片

类似与数学中的并集,补集,叠加。

此外,MergeNullValueHandling属性可以控制在合并是值为Null的要不要被忽略;


3.4 将Json类型转为普通类型

JObject对象中的成员类型并不是C#中类型,要变成普通类型,你需要使用:ToObject<T>() 做最后一步转换,其中T为你想转换为的类型,不进行转换直接打印可能会报错。

  1.  
    JValue v1 =
    new JValue(true);

  2.  
     
  3.  
    bool b = v1.ToObject<bool>();

  4.  
     
  5.  
    Console.WriteLine(b);

  6.  
    // true

  7.  
     
  8.  
    int i = v1.ToObject<int>();

  9.  
     
  10.  
    Console.WriteLine(i);

  11.  
    // 1

  12.  
     
  13.  
    string s = v1.ToObject<string>();

  14.  
     
  15.  
    Console.WriteLine(s);

  16.  
    // “True”

虽然很简单,但是刚接触NewtonJson可能会遇到这个问题。


3.5 判断Json文件是否相等 &深度复制Json文件

使用JToken.DeepEquals函数判断两个JObject对象是否相等,这个相等必须要所有属性值一模一样:

  1.  
    JValue s1 =
    new JValue(“A string”);

  2.  
    JValue s2 =
    new JValue(“A string”);

  3.  
    JValue s3 =
    new JValue(“A STRING”);

  4.  
     
  5.  
    Console.WriteLine(JToken.DeepEquals(s1, s2));

  6.  
    // true

  7.  
     
  8.  
    Console.WriteLine(JToken.DeepEquals(s2, s3));

  9.  
    // false

  10.  
     
  11.  
    JObject o1 =
    new JObject

  12.  
    {

  13.  
    {
    “Integer”, 12345 },

  14.  
    {
    “String”, “A string” },

  15.  
    {
    “Items”, new JArray(1, 2) }

  16.  
    };

  17.  
     
  18.  
    JObject o2 =
    new JObject

  19.  
    {

  20.  
    {
    “Integer”, 12345 },

  21.  
    {
    “String”, “A string” },

  22.  
    {
    “Items”, new JArray(1, 2) }

  23.  
    };

  24.  
     
  25.  
    Console.WriteLine(JToken.DeepEquals(o1, o2));

  26.  
    // true

  27.  
     
  28.  
    Console.WriteLine(JToken.DeepEquals(s1, o1[
    “String”]));

  29.  
    // true

注意:虽然两个json问价的内容一样,但是它们毕竟是2个不同的对象,使用JToken.RefernceEquals判断会返回false。

对于拷贝,主要是对内容进行拷贝,但是创建的是新对象:

  1.  
    JValue s1 =
    new JValue(“A string”);

  2.  
    JValue s2 =
    new JValue(“A string”);

  3.  
    JValue s3 =
    new JValue(“A STRING”);

  4.  
     
  5.  
    Console.WriteLine(JToken.DeepEquals(s1, s2));

  6.  
    // true

  7.  
     
  8.  
    Console.WriteLine(JToken.DeepEquals(s2, s3));

  9.  
    // false

  10.  
     
  11.  
    JObject o1 =
    new JObject

  12.  
    {

  13.  
    {
    “Integer”, 12345 },

  14.  
    {
    “String”, “A string” },

  15.  
    {
    “Items”, new JArray(1, 2) }

  16.  
    };

  17.  
     
  18.  
    JObject o2 =
    new JObject

  19.  
    {

  20.  
    {
    “Integer”, 12345 },

  21.  
    {
    “String”, “A string” },

  22.  
    {
    “Items”, new JArray(1, 2) }

  23.  
    };

  24.  
     
  25.  
    Console.WriteLine(JToken.DeepEquals(o1, o2));

  26.  
    // true

  27.  
     
  28.  
    Console.WriteLine(JToken.DeepEquals(s1, o1[
    “String”]));

  29.  
    // true


4. 总结

以上就是对NewtonJson的一点总结,很多是参考官方文档,我只选了一些常见的知识点进行介绍,建议大家遇到不能解决的问题时还是看官方文档。

一般而言,我更倾向与使用JObject对象处理Json,因为你可以获得JavaScript处理Json的90%的体验,使用起来很灵活,而且结合Linq语法,可以很方便的处理它。

 

转载地址:

https://blog.csdn.net/q__y__l/article/details/103566693#2.%E8%A7%A3%E6%9E%90Json%E6%96%87%E4%BB%B6