Newtonsoft.Json
- 简单介绍
- 代码示例
-
- 基本类型的序列化和反序列化
- 对象与集合的序列化和反序列化
- 自定义转换器的使用
- [动态类型和 LINQ to JSON](#动态类型和 LINQ to JSON)
-
- [使用动态类型解析未知结构的 JSON](#使用动态类型解析未知结构的 JSON)
- [使用 JObject 和 JToken](#使用 JObject 和 JToken)
- 忽略属性、更改属性名称、设置全局序列化选项
简单介绍
最常用的 JSON 处理库,功能丰富且经过广泛测试,支持复杂的序列化、反序列化、LINQ to JSON 等功能。它是.NET 项目中处理 JSON 的标准工具之一。
许可证
MIT 许可证(开源、免费,可用于商用)。
功能特点
- 支持复杂类型、动态类型和匿名类型。
- 支持数据验证、格式化、类型转换等。
- 支持高性能的流式 JSON 读取和写入。
- 提供与 .NET 类库的良好兼容性。
代码示例
基本类型的序列化和反序列化
cs
int number = 100;
string jsonNumber = JsonConvert.SerializeObject(number);
number = JsonConvert.DeserializeObject<int>(jsonNumber);
对象与集合的序列化和反序列化
定义一个简单的类:
cs
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
}
对象的序列化与反序列化
cs
Product product = new Product
{
ProductID = 1,
ProductName = "Laptop",
Price = 999.99m
};
string json = JsonConvert.SerializeObject(product, Formatting.Indented);
product = JsonConvert.DeserializeObject<Product>(json);
集合的序列化和反序列化
cs
List<Product> products = new List<Product>
{
new Product { ProductID = 1, ProductName = "Laptop", Price = 999.99m },
new Product { ProductID = 2, ProductName = "Smartphone", Price = 499.99m },
new Product { ProductID = 3, ProductName = "Tablet", Price = 299.99m }
};
string json = JsonConvert.SerializeObject(products, Formatting.Indented);
products = JsonConvert.DeserializeObject<List<Product>>(json);
自定义转换器的使用
自定义日期格式
假设有一个类,其中包含日期类型:
cs
public class Event
{
public string EventName { get; set; }
public DateTime EventDate { get; set; }
}
默认情况下,日期会序列化为 ISO 8601 格式。
如果想使用自定义格式,例如 yyyy-MM-dd,可以使用 JsonSerializerSettings。
cs
Event ev = new Event
{
EventName = "Conference",
EventDate = new DateTime(2023, 10, 1)
};
JsonSerializerSettings settings = new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd"
};
string json = JsonConvert.SerializeObject(ev, Formatting.Indented, settings);
ev = JsonConvert.DeserializeObject<Event>(json, settings);
自定义转换器处理特殊类型
假设有一个类,包含 TimeSpan 类型,而默认的序列化可能不满足需求。
cs
public class Task
{
public string TaskName { get; set; }
public TimeSpan Duration { get; set; }
}
创建自定义转换器:
cs
public class TimeSpanConverter : JsonConverter<TimeSpan>
{
public override void WriteJson(JsonWriter writer, TimeSpan value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
public override TimeSpan ReadJson(JsonReader reader, Type objectType, TimeSpan existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return TimeSpan.Parse((string)reader.Value);
}
}
使用自定义转换器进行序列化和反序列化
cs
Task task = new Task
{
TaskName = "Write Code",
Duration = new TimeSpan(2, 30, 0) // 2 小时 30 分钟
};
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new TimeSpanConverter());
string json = JsonConvert.SerializeObject(task, Formatting.Indented, settings);
task = JsonConvert.DeserializeObject<Task>(json, settings);
动态类型和 LINQ to JSON
使用动态类型解析未知结构的 JSON
当处理的 JSON 结构未知或动态变化时,可以使用 dynamic 类型。
示例 JSON:
json
{
"Name": "Alice",
"Age": 30,
"Skills": ["C#", "WPF", "JSON"]
}
解析动态 JSON:
cs
string json = @"{
""Name"": ""Alice"",
""Age"": 30,
""Skills"": [""C#"", ""WPF"", ""JSON""]
}";
dynamic obj = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine($"Name: {obj.Name}");
Console.WriteLine($"Age: {obj.Age}");
Console.WriteLine("Skills:");
foreach (var skill in obj.Skills)
{
Console.WriteLine($"- {skill}");
}
使用 JObject 和 JToken
cs
using Newtonsoft.Json.Linq;
string json = @"{
""Name"": ""Alice"",
""Age"": 30,
""Skills"": [""C#"", ""WPF"", ""JSON""]
}";
JObject obj = JObject.Parse(json);
// 读取值
string name = (string)obj["Name"];
int age = (int)obj["Age"];
JArray skills = (JArray)obj["Skills"];
// 添加新属性
obj["Country"] = "China";
// 删除属性
obj.Property("Age").Remove();
// 遍历所有属性
foreach (var property in obj.Properties())
{
Console.WriteLine($"{property.Name}: {property.Value}");
}
// 输出修改后的 JSON
string modifiedJson = obj.ToString();
Console.WriteLine(modifiedJson);
输出:
json
Name: Alice
Skills: ["C#","WPF","JSON"]
Country: China
{
"Name": "Alice",
"Skills": [
"C#",
"WPF",
"JSON"
],
"Country": "China"
}
忽略属性、更改属性名称、设置全局序列化选项
忽略某些属性
使用 [JsonIgnore] 特性可以在序列化和反序列化时忽略某些属性。
定义一个简单的类:
csharp
public class User
{
public string UserName { get; set; }
[JsonIgnore]
public string Password { get; set; }
}
示例:
csharp
User user = new User
{
UserName = "Alice",
Password = "secret"
};
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);
输出的 JSON(Password 被忽略):
json
{
"UserName": "Alice"
}
更改属性名称
使用 [JsonProperty] 特性可以更改序列化时的属性名称。
定义一个简单的类:
csharp
public class User
{
[JsonProperty("user_name")]
public string UserName { get; set; }
public string Email { get; set; }
}
示例:
csharp
User user = new User
{
UserName = "Alice",
Email = "alice@example.com"
};
string json = JsonConvert.SerializeObject(user, Formatting.Indented);
Console.WriteLine(json);
输出的 JSON(UserName 被更改为 user_name):
json
{
"user_name": "Alice",
"Email": "alice@example.com"
}
设置全局序列化选项
可以通过 JsonSerializerSettings 设置全局的序列化和反序列化选项。
定义一个简单的类:
csharp
public class User
{
public string UserName { get; set; }
public string Email { get; set; }
}
示例:忽略空值
csharp
User user = new User
{
UserName = "Alice",
};
JsonSerializerSettings settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
string json = JsonConvert.SerializeObject(user, Formatting.Indented, settings);
Console.WriteLine(json);
输出的 JSON(Email 被忽略了):
json
{
"UserName": "Alice"
}