开源库入门教程 Newtonsoft.JsonJSON.NET库
文章目录
前言
说起.NET开发中的JSON处理,Newtonsoft.Json绝对是个老朋友了!这个库从2007年就开始服务开发者,到现在依然是最受欢迎的JSON处理库之一。虽然.NET Core后来推出了System.Text.Json,但Newtonsoft.Json凭借其强大的功能和灵活性,依然占据着重要地位。
今天咱们就来聊聊这个经典库,看看它到底有什么魅力,能让这么多开发者爱不释手!
什么是Newtonsoft.Json
Newtonsoft.Json,也叫JSON.NET,是一个高性能的.NET JSON框架。它能够轻松地在.NET对象和JSON之间进行转换,支持序列化和反序列化操作。
这个库的创建者James Newton-King(没错,库名就是从他的姓氏来的)真的是个天才!他创造了一个既强大又易用的工具。
主要特性
- 高性能 - 比其他JSON库快很多
- 灵活的API - 提供多种使用方式
- LINQ to JSON - 可以像操作XML一样操作JSON
- 丰富的序列化选项 - 各种自定义设置
- 跨平台支持 - .NET Framework、.NET Core、Mono等都支持
安装与配置
NuGet包管理器安装
最简单的方式就是通过NuGet安装:
Install-Package Newtonsoft.Json
或者在Visual Studio的包管理器UI中搜索"Newtonsoft.Json"直接安装。
项目文件配置
如果你用的是.NET Core/.NET 5+项目,也可以直接在csproj文件中添加:
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
然后restore一下就好了。
基础用法
序列化:对象转JSON
最基本的操作就是把C#对象转换成JSON字符串:
using Newtonsoft.Json;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
// 创建对象
var person = new Person
{
Name = "张三",
Age = 25,
Email = "zhangsan@example.com"
};
// 序列化为JSON
string json = JsonConvert.SerializeObject(person);
Console.WriteLine(json);
// 输出:{"Name":"张三","Age":25,"Email":"zhangsan@example.com"}
简单吧!一行代码就搞定了。
反序列化:JSON转对象
反过来,我们也可以把JSON字符串转换成C#对象:
string jsonString = @"{
'Name': '李四',
'Age': 30,
'Email': 'lisi@example.com'
}";
Person person = JsonConvert.DeserializeObject<Person>(jsonString);
Console.WriteLine($"姓名:{person.Name}, 年龄:{person.Age}");
注意这里用的是泛型方法,直接指定了目标类型,超级方便!
处理复杂对象
实际项目中,我们经常要处理嵌套对象、集合等复杂结构:
public class Company
{
public string Name { get; set; }
public List<Person> Employees { get; set; }
public Dictionary<string, object> Metadata { get; set; }
}
var company = new Company
{
Name = "科技公司",
Employees = new List<Person>
{
new Person { Name = "王五", Age = 28, Email = "wangwu@tech.com" },
new Person { Name = "赵六", Age = 32, Email = "zhaoliu@tech.com" }
},
Metadata = new Dictionary<string, object>
{
["founded"] = 2020,
["location"] = "北京",
["isPublic"] = false
}
};
string json = JsonConvert.SerializeObject(company, Formatting.Indented);
这里用了Formatting.Indented参数,让输出的JSON格式更好看,方便阅读。
高级特性
自定义序列化设置
有时候默认的序列化行为不能满足我们的需求,这时候就需要自定义设置了:
var settings = new JsonSerializerSettings
{
// 忽略null值
NullValueHandling = NullValueHandling.Ignore,
// 日期格式化
DateFormatString = "yyyy-MM-dd HH:mm:ss",
// 属性命名策略(驼峰命名)
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
string json = JsonConvert.SerializeObject(person, settings);
使用特性标记
通过特性(Attribute)可以更精细地控制序列化行为:
public class User
{
[JsonProperty("user_name")]
public string Name { get; set; }
[JsonIgnore]
public string Password { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Phone { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public UserType Type { get; set; }
}
public enum UserType
{
Regular,
Premium,
Admin
}
这样设置后:
- Name属性在JSON中会显示为"user_name"
- Password属性完全不会出现在JSON中
- Phone属性如果为null就不显示
- Type枚举会显示为字符串而不是数字
LINQ to JSON
这是Newtonsoft.Json的一个杀手锏功能!可以像操作XML一样动态处理JSON:
string jsonText = @"{
'users': [
{ 'name': '小明', 'age': 25, 'city': '上海' },
{ 'name': '小红', 'age': 23, 'city': '北京' },
{ 'name': '小刚', 'age': 27, 'city': '深圳' }
]
}";
JObject json = JObject.Parse(jsonText);
// 查询年龄大于24的用户
var adults = json["users"]
.Where(u => (int)u["age"] > 24)
.Select(u => new {
Name = (string)u["name"],
City = (string)u["city"]
});
foreach (var user in adults)
{
Console.WriteLine($"{user.Name} 来自 {user.City}");
}
这种方式特别适合处理结构不固定的JSON数据。
动态处理JSON
有时候我们不知道JSON的具体结构,可以用dynamic来处理:
string json = @"{ 'name': '动态对象', 'count': 42, 'active': true }";
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine($"名称:{obj.name}");
Console.WriteLine($"数量:{obj.count}");
Console.WriteLine($"状态:{obj.active}");
虽然这样很灵活,但要注意类型安全问题。
性能优化技巧
重用JsonSerializer
如果要进行大量的序列化操作,创建一个JsonSerializer实例重复使用会更高效:
var serializer = new JsonSerializer();
serializer.NullValueHandling = NullValueHandling.Ignore;
using (var writer = new StringWriter())
{
serializer.Serialize(writer, person);
string json = writer.ToString();
}
流式处理大文件
处理大JSON文件时,使用流式API可以避免内存溢出:
using (var reader = new JsonTextReader(new StringReader(largeJsonString)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
{
string propertyName = reader.Value.ToString();
// 处理属性
}
}
}
实际应用场景
Web API开发
在ASP.NET Web API中,Newtonsoft.Json经常用于配置序列化行为:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
}
配置文件处理
读写JSON配置文件也是常见场景:
public class AppConfig
{
public string DatabaseConnection { get; set; }
public int TimeoutSeconds { get; set; }
public bool EnableLogging { get; set; }
}
// 读取配置
string configText = File.ReadAllText("appsettings.json");
AppConfig config = JsonConvert.DeserializeObject<AppConfig>(configText);
// 保存配置
string updatedJson = JsonConvert.SerializeObject(config, Formatting.Indented);
File.WriteAllText("appsettings.json", updatedJson);
缓存序列化
把对象序列化后存到Redis等缓存系统:
public void CacheUser(User user)
{
string json = JsonConvert.SerializeObject(user);
// 存储到Redis
cache.Set($"user:{user.Id}", json, TimeSpan.FromHours(1));
}
public User GetCachedUser(int userId)
{
string json = cache.Get($"user:{userId}");
return json != null ? JsonConvert.DeserializeObject<User>(json) : null;
}
常见问题与解决方案
循环引用问题
当对象之间存在循环引用时,序列化会出错:
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(objectWithCircularReference, settings);
时区处理
处理DateTime时要注意时区问题:
var settings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ"
};
大小写敏感
JSON属性名大小写不匹配时:
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
};
与System.Text.Json对比
虽然.NET Core引入了System.Text.Json,但两者各有优劣:
Newtonsoft.Json优势:
- 功能更丰富,支持更多数据类型
- LINQ to JSON功能强大
- 自定义选项更多
- 社区支持更好
System.Text.Json优势:
- 性能更好
- 内存占用更少
- 更安全(默认不支持循环引用)
选择哪个主要看项目需求。如果需要复杂的JSON操作,Newtonsoft.Json依然是首选!
总结
Newtonsoft.Json确实是个优秀的库,它的强大之处在于:
- 简单易用 - 基础功能一行代码搞定
- 功能丰富 - 各种高级特性应有尽有
- 灵活性高 - 可以精细控制序列化行为
- 性能不错 - 虽然不是最快的,但够用了
- 稳定可靠 - 经过多年验证,bug很少
对于.NET开发者来说,掌握Newtonsoft.Json是必备技能。无论是写Web API、处理配置文件,还是做数据交换,都能派上用场。
当然,随着.NET生态的发展,System.Text.Json也在快速进步。但Newtonsoft.Json的地位短期内还是很难撼动的。毕竟,一个经过十多年打磨的库,真的不是盖的!
学会了这些基础知识,你就可以在项目中愉快地使用Newtonsoft.Json了。记住,实践是最好的老师,多写代码,多踩坑,才能真正掌握这个强大的工具!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)