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"
}
相关推荐
快下雨了L3 小时前
C++面试笔记(持续更新...)
笔记
柃歌4 小时前
【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
java·数据结构·笔记·学习·算法
JANGHIGH4 小时前
c++ std::list使用笔记
c++·笔记·list
柃歌4 小时前
【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记
java·数据结构·笔记·学习·算法
大溪地C4 小时前
Git 合并冲突解决与状态分析笔记
笔记·git
BUG 劝退师5 小时前
C语言预处理学习笔记
c语言·笔记·学习
花王江不语7 小时前
设计模式学习笔记
笔记·学习·设计模式
前端熊猫7 小时前
CSS Grid 布局学习笔记
css·笔记·学习·grid
肥肠可耐的西西公主9 小时前
前端(AJAX)学习笔记(CLASS 2):图书管理案例以及图片上传
前端·笔记·学习
Long_poem9 小时前
【自学笔记】Spring Boot框架技术基础知识点总览-持续更新
spring boot·笔记·后端