C#JSON教程展示了如何使用标准库的类在C#中处理JSON数据。
JSON
JSON(JavaScript对象表示法)是一种轻量级数据交换格式。它很容易被人类阅读和编写,并被机器解析和生成。application/json
是JSON的官方互联网媒体类型。JSON文件扩展名为.json
。
在本文中,我们使用C#标准库。还有一个名为Json.NET
的流行第三方库。
系统.Text.Json
System.Text.Json
命名空间提供高性能、低分配且符合标准的工具来处理JSON。这些类允许我们将对象序列化为JSON文本并将JSON文本反序列化为对象。UTF-8支持是内置的。
C#JSON解析
JsonDocument.Parse
将流解析为UTF-8编码数据,将单个JSON值表示为JsonDocument
。流被读取完成。
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; using JsonDocument doc = JsonDocument.Parse(data); JsonElement root = doc.RootElement; Console.WriteLine(root); var u1 = root[0]; var u2 = root[1]; Console.WriteLine(u1); Console.WriteLine(u2); Console.WriteLine(u1.GetProperty("name")); Console.WriteLine(u1.GetProperty("occupation")); Console.WriteLine(u2.GetProperty("name")); Console.WriteLine(u2.GetProperty("occupation"));
在示例中,我们解析了一个简单的JSON字符串。
using JsonDocument doc = JsonDocument.Parse(data);
我们将JSON字符串解析为JsonDocument
。
JsonElement root = doc.RootElement;
我们使用RootElement
属性获取对根元素的引用。
var u1 = root[0]; var u2 = root[1]; Console.WriteLine(u1); Console.WriteLine(u2);
使用[]
运算符,我们获取JSON文档的第一个和第二个子元素。
Console.WriteLine(u1.GetProperty("name")); Console.WriteLine(u1.GetProperty("occupation"));
我们使用GetProperty
获取元素的属性。
$ dotnet run [ {"name": "John Doe", "occupation": "gardener"}, {"name": "Peter Novak", "occupation": "driver"} ] {"name": "John Doe", "occupation": "gardener"} {"name": "Peter Novak", "occupation": "driver"} John Doe gardener Peter Novak driver
C#JSON枚举
JsonElement.EnumerateArray
枚举由JsonElement
表示的JSONarray中的值。
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; using var doc = JsonDocument.Parse(data); JsonElement root = doc.RootElement; var users = root.EnumerateArray(); while (users.MoveNext()) { var user = users.Current; System.Console.WriteLine(user); var props = user.EnumerateObject(); while (props.MoveNext()) { var prop = props.Current; Console.WriteLine($"{prop.Name}: {prop.Value}"); } }
在示例中,我们枚举了根元素的内容。
var users = root.EnumerateArray();
我们有子元素数组。
while (users.MoveNext()) { var user = users.Current; Console.WriteLine(user); ...
在while循环中,我们遍历元素数组。
var props = user.EnumerateObject(); while (props.MoveNext()) { var prop = props.Current; Console.WriteLine($"{prop.Name}: {prop.Value}"); }
在第二个while循环中,我们检查每个元素的属性。
$ dotnet run {"name": "John Doe", "occupation": "gardener"} name: John Doe occupation: gardener {"name": "Peter Novak", "occupation": "driver"} name: Peter Novak occupation: driver
C#JSON序列化
JsonSerializer.Serialize
将指定类型的值转换为JSON字符串。
using System.Text.Json; var user = new User("John Doe", "gardener", new MyDate(1995, 11, 30)); var json = JsonSerializer.Serialize(user); Console.WriteLine(json); record MyDate(int year, int month, int day); record User(string Name, string Occupation, MyDate DateOfBirth);
在示例中,我们将User
对象转换为JSON字符串。
$ dotnet run {"Name":"John Doe","Occupation":"gardener", "DateOfBirth":{"year":1995,"month":11,"day":30}}
反序列化C#JSON
JsonSerializer.Deserialize
将表示单个JSON值的文本解析为指定类型的实例。
using System.Text.Json; string json = @"{""Name"":""John Doe"", ""Occupation"":""gardener"", ""DateOfBirth"":{""year"":1995,""month"":11,""day"":30}}"; var user = JsonSerializer.Deserialize<User>(json); Console.WriteLine(user); Console.WriteLine(user?.Name); Console.WriteLine(user?.Occupation); Console.WriteLine(user?.DateOfBirth); record MyDate(int year, int month, int day); record User(string Name, string Occupation, MyDate DateOfBirth);
该示例将JSON字符串解析为User
类型的实例。
C#JsonSerializerOptions
使用JsonSerializerOptions
,我们可以通过一些选项控制序列化过程。
using System.Text.Json; var words = new Dictionary<int, string> { {1, "sky"}, {2, "cup"}, {3, "odd"}, {4, "cloud"}, {5, "forest"}, {6, "warm"}, }; var r = JsonSerializer.Serialize(words, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(r); Console.WriteLine("---------------------"); var d = JsonSerializer.Deserialize<Dictionary<int, string>>(r); foreach (var (k, v) in d!) { Console.WriteLine($"{k}: {v}"); }
通过设置WriteIndented
选项,我们可以为漂亮的打印启用缩进。
$ dotnet run { "1": "sky", "2": "cup", "3": "odd", "4": "cloud", "5": "forest", "6": "warm" } --------------------- 1: sky 2: cup 3: odd 4: cloud 5: forest 6: warm
C#Utf8JsonWriter
Utf8JsonWriter
提供了一个高性能API,用于只转发、非缓存的UTF-8编码JSON文本写入。
using System.Text.Json; using System.Text; using var ms = new MemoryStream(); using var writer = new Utf8JsonWriter(ms); writer.WriteStartObject(); writer.WriteString("name", "John Doe"); writer.WriteString("occupation", "gardener"); writer.WriteNumber("age", 34); writer.WriteEndObject(); writer.Flush(); string json = Encoding.UTF8.GetString(ms.ToArray()); Console.WriteLine(json);
在示例中,我们创建了一个新对象并将其写入JSON字符串。
$ dotnet run {"name":"John Doe","occupation":"gardener","age":34}
我们可以将Indented
选项设置为true
来美化JSON输出。
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; JsonDocument jdoc = JsonDocument.Parse(data); var fileName = @"data.json"; using FileStream fs = File.OpenWrite(fileName); using var writer = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true }); jdoc.WriteTo(writer);
在示例中,我们将JSON字符串写入文件。数据已美化。
$ cat data.json [ { "name": "John Doe", "occupation": "gardener" }, { "name": "Peter Novak", "occupation": "driver" } ]
C#JSONUtf8JsonReader
Utf8JsonReader
提供了一个高性能API,用于对UTF-8编码的JSON文本进行只进、只读访问。
using System.Text.Json; var fileName = @"/home/user7/data.json"; byte[] data = File.ReadAllBytes(fileName); Utf8JsonReader reader = new Utf8JsonReader(data); while (reader.Read()) { switch (reader.TokenType) { case JsonTokenType.StartObject: Console.WriteLine("-------------"); break; case JsonTokenType.EndObject: break; case JsonTokenType.StartArray: case JsonTokenType.EndArray: break; case JsonTokenType.PropertyName: Console.Write($"{reader.GetString()}: "); break; case JsonTokenType.String: Console.WriteLine(reader.GetString()); break; default: throw new ArgumentException(); } }
在示例中,我们使用Utf8JsonReader
从文件中读取JSON数据。它提供了一个用于读取JSON数据的低级API。我们逐个令牌读取数据令牌。
$ dotnet run ------------- name: John Doe occupation: gardener ------------- name: Peter Novak occupation: driver
C#JSON异步解析
在下面的示例中,我们使用JsonDocument.ParseAsync
异步读取流。
using System.Text.Json; using var httpClient = new HttpClient(); var url = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases-index.json"; var ts = await httpClient.GetStreamAsync(url); using var resp = await JsonDocument.ParseAsync(ts); var root = resp.RootElement.GetProperty("releases-index"); var elems = root.EnumerateArray(); while (elems.MoveNext()) { var node = elems.Current; Console.WriteLine(node); }
该示例读取.NETCore框架的所有版本,这些版本在项目Github存储库中以JSON字符串的形式提供。
C#HttpClientGetFromJsonAsync
GetFromJsonAsync
方法向指定的URL发送GET请求,并返回在异步操作中将响应正文反序列化为JSON所产生的值。
该方法是System.Net.Http.Json
的扩展方法。
using System.Text.Json.Serialization; using System.Net.Http.Json; using var client = new HttpClient(); var url = "http://webcode.me/users.json"; var data = await client.GetFromJsonAsync<Users>(url); if (data != null) { foreach (var user in data.users) { Console.WriteLine(user); } } class Users { public List<User> users { get; set; } = new(); } class User { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } = string.Empty; [JsonPropertyName("last_name")] public string LastName { get; set; } = string.Empty; [JsonPropertyName("email")] public string Email { get; set; } = string.Empty; public override string ToString() { return $"User {{ {Id}| {FirstName} {LastName}| {Email} }}"; } }
我们创建一个对JSON资源的异步http请求。JSON数据被序列化为User
对象列表。
var data = await client.GetFromJsonAsync<Users>(url);
GetFromJsonAsync
是一种将JSON资源转换为C#集合的便捷方法。
class Users { public List<User> users { get; set; } = new(); }
我们需要为List
集合创建一个特定的类。
class User { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } = string.Empty; [JsonPropertyName("last_name")] public string LastName { get; set; } = string.Empty; [JsonPropertyName("email")] public string Email { get; set; } = string.Empty; public override string ToString() { return $"User {{ {Id}| {FirstName} {LastName}| {Email} }}"; } }
JSON字段映射到类属性。
$ dotnet run User { 1| Robert Schwartz| rob23@gmail.com } User { 2| Lucy Ballmer| lucyb56@gmail.com } User { 3| Anna Smith| annasmith23@gmail.com } User { 4| Robert Brown| bobbrown432@yahoo.com } User { 5| Roger Bacon| rogerbacon12@yahoo.com }
在本文中,我们在C#中处理了JSON数据。
列出所有C#教程。