Newtonsoft.Json (Json.NET)使用笔记

Newtonsoft.Json

简单介绍

最常用的 JSON 处理库,功能丰富且经过广泛测试,支持复杂的序列化、反序列化、LINQ to JSON 等功能。它是.NET 项目中处理 JSON 的标准工具之一。

许可证

MIT 许可证(开源、免费,可用于商用)。

功能特点

  1. 支持复杂类型、动态类型和匿名类型。
  2. 支持数据验证、格式化、类型转换等。
  3. 支持高性能的流式 JSON 读取和写入。
  4. 提供与 .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"
}
相关推荐
小羊没烦恼!4 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
一隅论数智4 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
譕痕4 天前
JSONObject与JSONArray封装数据格式区别
java·json
A黄俊辉A4 天前
uniapp webview中实现 app和内嵌的H5双向通信
vue.js·json
深圳老胡4 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
Because_of_Her14 天前
并查集-听课笔记
笔记·算法·并查集
彧azz4 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
陈卫军老师4 天前
陈卫军:把口味写在一张纸上,店才稳得住
经验分享·笔记·流量运营
`流年づ4 天前
人工智能学习笔记 - 补充
人工智能·笔记·深度学习·学习
qeen874 天前
【Linux】操作系统之进程介绍(二)
linux·笔记·学习·进程