作为 .NET 的新手,我正在学习在 C# 中使用 JSON 反序列化。如何有效地将具有嵌套属性的对象的 JSON 数组反序列化为 C# 实例列表,同时有效处理解除嵌套过程?
我有一个 JSON 数组,表示具有嵌套属性的对象列表,如下所示:
[
{"name":"apple","properties":{"color":"red","flavor":"sweet"}},
{"name":"orange","properties":{"color":"orange","flavor":"sour"}}
]
我想将此 JSON 反序列化为 C# 对象列表。 C# 类如下所示:
public class Fruit
{
public string Name { get; set; }
public string Color { get; set; }
public string Flavor { get; set; }
}
需要注意的是,C# 对象(Fruit)的结构与 JSON 对象的结构不同。特别是,C# 对象没有“属性”变量。
是否有比手动迭代 JSON 数组元素并向 Fruit 对象赋值更有效的方法来实现此目的?
using System;
using System.Collections.Generic;
using System.Text.Json;
public class Fruit
{
public string Name { get; set; }
public string Color { get; set; }
public string Flavor { get; set; }
}
class Program
{
static void Main()
{
string json = "[{\"name\":\"apple\",\"properties\":{\"color\":\"red\",\"flavor\":\"sweet\"}},{\"name\":\"orange\",\"properties\":{\"color\":\"orange\",\"flavor\":\"sour\"}}]";
// Deserialize into a list of Fruit objects
List<Fruit> fruits = new List<Fruit>();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var jsonObjects = JsonSerializer.Deserialize<List<JsonElement>>(json, options);
foreach (var jsonObject in jsonObjects)
{
var fruit = new Fruit
{
Name = jsonObject.GetProperty("name").GetString(),
Color = jsonObject.GetProperty("properties").GetProperty("color").GetString(),
Flavor = jsonObject.GetProperty("properties").GetProperty("flavor").GetString()
};
fruits.Add(fruit);
}
// Print the fruits
foreach (var fruit in fruits)
{
Console.WriteLine("Name: " + fruit.Name);
Console.WriteLine("Color: " + fruit.Color);
Console.WriteLine("Flavor: " + fruit.Flavor);
Console.WriteLine();
}
}
}
您有多种方法可以做到这一点。我想我会为此使用自定义转换器,因为:
public class FruitConverter : JsonConverter<Fruit>
{
public override Fruit Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Fruit fruit = new Fruit();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return fruit;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "name":
fruit.Name = reader.GetString();
break;
case "properties":
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
string prop = reader.GetString();
reader.Read();
if (prop == "color")
fruit.Color = reader.GetString();
else if (prop == "flavor")
fruit.Flavor = reader.GetString();
}
}
break;
}
}
}
throw new Exception("json is not fotmatted well");
}
public override void Write(Utf8JsonWriter writer, Fruit value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("name", value.Name);
writer.WriteStartObject("properties");
writer.WriteString("color", value.Color);
writer.WriteString("flavor", value.Flavor);
writer.WriteEndObject();
writer.WriteEndObject();
}
}