C# 使用Newtonsoft.Json进行对象序列化、JSON反序列化的方法
JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,Newtonsoft.Json无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询。
零、安装Newtonsoft.Json

零、全局公共类
public class Account
{
public string Name { get; set; }
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList<string> Roles { get; set; }
}一、对象序列化
1、通过Newtonsoft.Json.Formatting将json格式化输出
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Account account = new Account
{
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
Roles = new List<string> { "User", "Admin" }
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

2、序列化List集合:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
List<string> videogames = new List<string> { "HTML5", "JQ", ".NET", "C#", ".NET core" };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(videogames);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

3、序列化Dictionary
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> dic = new Dictionary<string, string>
{
{ "Name", "李飞" },
{ "Age", "34" },
{ "Email", "546262132@qq.com" }
};
string json1 = JsonConvert.SerializeObject(dic, Formatting.Indented);
Console.WriteLine("格式化:");
Console.WriteLine(json1);
Console.WriteLine("未格式化:");
string json2 = JsonConvert.SerializeObject(dic, Formatting.None);
Console.WriteLine(json2);
Console.Read();
}
}
}输出结果:

4、基于枚举类型的JsonConverters转换器
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
//单独取名称或值的方式
List<JosnEnum> list = new List<JosnEnum>{ JosnEnum.NotStartus, JosnEnum.Startus };
string json = JsonConvert.SerializeObject(list);
string json3 = JsonConvert.SerializeObject(list, new Newtonsoft.Json.Converters.StringEnumConverter());
Console.WriteLine(json);
Console.WriteLine(json3);
//Dictionary形式取名称和值
Dictionary<string, int> dic = new Dictionary<string, int>
{
{((JosnEnum)(int)JosnEnum.NotStartus).ToString() ,(int)JosnEnum.NotStartus} ,
{((JosnEnum)(int)JosnEnum.Startus).ToString() ,(int)JosnEnum.Startus}
};
string dicJson = JsonConvert.SerializeObject(dic);
Console.WriteLine(dicJson);
//取名称,逗号间隔格式化输出
List<JosnEnum> result = JsonConvert.DeserializeObject<List<JosnEnum>>(json3, new Newtonsoft.Json.Converters.StringEnumConverter());
Console.WriteLine(string.Join(",", result.Select(c => c.ToString())));
Console.Read();
}
public enum JosnEnum
{
NotStartus = 0,
Startus = 1
}
}
}输出结果:

5、序列化var匿名类型
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
var test1 = new { Name = "李飞", Age = 36 };
var json = JsonConvert.SerializeObject(test1);
Console.WriteLine(json);
var test2 = new { Name = "", Age = 0 };
string json1 = @"{'Name':'张飞','Age':'35'}";
var result = JsonConvert.DeserializeAnonymousType(json1, test2);
Console.WriteLine(result.Name);
Console.Read();
}
}
}输出结果:

二、JSON反序列化
1、将json反序列化对象
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
string json = @"{
'Name': 'lifei',
'Email': '546262132@qq.com',
'Active': true,
'CreatedDate': '2024-01-04 23:45:04',
'Roles': ['User','Admin']
}";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine("姓名:" + account.Name +",邮箱:"+ account.Email);
Console.Read();
}
}
}输出结果:

2、反序列化List集合
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
string json = @"['Html5','C#','.Net','.Net Core']";
List<string> videogames = JsonConvert.DeserializeObject<List<string>>(json);
Console.WriteLine(string.Join(",", videogames));
Console.Read();
}
}
}输出结果:

3、反序列化Dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
string json = @"{'Name': '李飞','Age': '23'}";
var Attributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(Attributes["Name"]);
Console.WriteLine(Attributes["Age"]);
Console.Read();
}
}
}输出结果:

4、反序列化var匿名类型
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
var test2 = new { Name = "", Age = 0 };
string json1 = @"{'Name':'张飞','Age':'35'}";
var result = JsonConvert.DeserializeAnonymousType(json1, test2);
Console.WriteLine(result.Name);
Console.Read();
}
}
}输出结果:

三、特殊的使用方法
1、用新JSON字符串填充指定对象的属性值
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Account account = new Account
{
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
Roles = new List<string> { "User", "Admin" }
};
string json = @"{'Active': false, 'Roles': ['Expired']}";
JsonConvert.PopulateObject(json, account);
Console.WriteLine(account.Active);
Console.WriteLine(account.Email);
Console.Read();
}
}
}输出结果:

2、当对象的属性为默认值(0或null)时不序列化该属性
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Account account1 = new Account();
string json1 = JsonConvert.SerializeObject(account1, Formatting.Indented, new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
});
Console.WriteLine(json1);
Console.WriteLine("");
Account account2 = new Account() { Name = "李飞" };
string json2 = JsonConvert.SerializeObject(account2, Formatting.Indented, new Newtonsoft.Json.JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
});
Console.WriteLine(json2);
Console.Read();
}
}
}输出结果:

3、忽略null值序列化
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Account account = new Account { Name = "李飞", Email = "546262132@qq.com" };
string jsonIncludeNull = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(jsonIncludeNull);
string json = JsonConvert.SerializeObject(account, Formatting.Indented, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

4、循环引用的处理方法(对象嵌套类型)
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Employee employee1 = new Employee { Name = "张飞" };
Employee employee2 = new Employee { Name = "李飞" };
employee1.Manager = employee2;
employee2.Manager = employee1;
string json = JsonConvert.SerializeObject(employee1, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
Console.WriteLine(json);
string json2 = JsonConvert.SerializeObject(employee2, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
Console.WriteLine(json2);
Console.Read();
}
public class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }
}
}
}输出结果:

或者变成这个样子
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Employee employee1 = new Employee { Name = "张飞" };
EmployeeManager employee2 = new EmployeeManager { Name = "李飞", Manager = "测试" };
employee1.Manager = employee2;
string json = JsonConvert.SerializeObject(employee1, Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
Console.WriteLine(json);
Console.Read();
}
public class Employee
{
public string Name { get; set; }
public EmployeeManager Manager { get; set; }
}
public class EmployeeManager
{
public string Name { get; set; }
public string Manager { get; set; }
}
}
}输出结果:

5、通过ContractResolver指定属性名首字母小写
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
static void Main(string[] args)
{
Account account = new Account
{
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
Roles = new List<string> { "User", "Admin" }
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented, new JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
});
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

6、通过特性序列化枚举类型
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public enum ProductStatus
{
NotConfirmed,
Active, Deleted
}
public class Product
{
public string Name { get; set; }
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public ProductStatus Status { get; set; }
}
static void Main(string[] args)
{
Product user = new Product { Name = "羽绒服", Status = ProductStatus.Deleted };
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

7、指定需要序列化的属性
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
[JsonObject(MemberSerialization.OptIn)]
public class Categroy
{
//Id不需要序列化
public Guid Id { get; set; }
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public int Size { get; set; }
}
static void Main(string[] args)
{
Categroy categroy = new Categroy
{
Id = Guid.NewGuid(),
Name = "上衣",
Size = 185
};
string json = JsonConvert.SerializeObject(categroy, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

8、序列化对象时指定属性名
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("active")]
public bool Active { get; set; }
[JsonProperty("createdate")]
public DateTime CreatedDate { get; set; }
}
static void Main(string[] args)
{
Account account = new Account
{
Name = "李飞",
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

9、指定属性在JSON中的顺序
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty(Order = 2)]
public string Name { get; set; }
[JsonProperty(Order = 1)]
public string Email { get; set; }
[JsonProperty("active")]
public bool Active { get; set; }
[JsonProperty("createdate")]
public DateTime CreatedDate { get; set; }
}
static void Main(string[] args)
{
Account account = new Account
{
Name = "李飞",
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

默认的排序Order = 1
10、反序列化指定属性是否必须有值必须不为null
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
public string Email { get; set; }
public bool Active { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public DateTime? CreatedDate { get; set; }
}
static void Main(string[] args)
{
string json = @"{
'Name': 'lifei',
'Email': '546262132@qq.com',
'Active': true,
'CreatedDate': null
}";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Name);
Console.WriteLine(account.CreatedDate);
Console.Read();
}
}
}输出结果:

通过JsonProperty特性的Required指定反序列化行为,当反序列化行为与指定的行为不匹配时,将抛出异常,Required是枚举,Required.Always表示属性必须有值切不能为null,Required.AllowNull表示属性必须有值,但允许为null值。
11、通过特性指定null值忽略序列化
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
public bool Active { get; set; }
[JsonProperty(Required = Required.AllowNull, NullValueHandling = NullValueHandling.Ignore)]
public DateTime? CreatedDate { get; set; }
public string Email { get; set; }
}
static void Main(string[] args)
{
Account account = new Account
{
Name = "李飞",
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

12、忽略不需要序列化的属性,JsonIgnore
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonIgnore]
public bool Active { get; set; }
[JsonProperty(Required = Required.AllowNull, NullValueHandling = NullValueHandling.Ignore)]
public DateTime? CreatedDate { get; set; }
public string Email { get; set; }
}
static void Main(string[] args)
{
Account account = new Account
{
Name = "李飞",
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
};
string json = JsonConvert.SerializeObject(account, Formatting.Indented);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

13、序列化或反序列化时指定日期时间格式,JsonSerializerSettings的设置对象DateFormatString属性指定日期时间格式
using System;
using Newtonsoft.Json;
namespace NewtonsoftJson
{
class Program
{
public class Account
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonIgnore]
public bool Active { get; set; }
[JsonProperty(Required = Required.AllowNull, NullValueHandling = NullValueHandling.Ignore)]
public DateTime? CreatedDate { get; set; }
public string Email { get; set; }
}
static void Main(string[] args)
{
Account account = new Account
{
Name = "李飞",
Email = "546262132@qq.com",
Active = true,
CreatedDate = DateTime.Now,
};
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd HH:mm:ss",
Formatting = Formatting.Indented
};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(account, settings);
Console.WriteLine(json);
Console.Read();
}
}
}输出结果:

14、将DataTable转成Json
static void Main(string[] args)
{
//这里忽略了datatable的获取方法
DataTable dt;
string str = ToJson(dt);
}
public static string ToJson(this DataTable dt)
{
return JsonConvert.SerializeObject(dt, Formatting.None, new Newtonsoft.Json.Converters.DataTableConverter());
}

