开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C# JSON

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#教程。

未经允许不得转载:我爱分享网 » C# JSON

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏