.NET 中的自定义 JSON 转换器

科技   2024-11-14 16:46   上海  


在 .NET 中使用 JSON 时,我们经常使用标准序列化程序来序列化模型。但是,有时我们需要自定义序列化以满足特定的客户要求,同时保持我们的模型简洁明了。这就是自定义 JSON 转换器派上用场的地方。

在本文中,我将向您展示如何使用 .System.Text.Json

如何添加自定义 JSON 转换器

您不需要任何其他库即可开始使用 — 只需实现接口即可。JsonConverter

第 1 步:定义模型

首先,我们定义一个模型,用于序列化和反序列化 JSON。

public record Person(string FirstName, string LastName, DateOnly Birthday);

第 2 步:添加自定义 JSON 转换器

接下来,我们将为该类创建自定义 JSON 转换器。Person

public class PersonJsonConverter : JsonConverter<Person>  
{
public override Person? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

using var jsonDocument = JsonDocument.ParseValue(ref reader);
var firstName = jsonDocument.RootElement.GetProperty("firstName").GetString();
var lastName = jsonDocument.RootElement.GetProperty("lastName").GetString();
var birthday = DateOnly.Parse(jsonDocument.RootElement.GetProperty("birthday").GetString()!);

return new Person(firstName!, lastName!, birthday);
}

public override void Write(Utf8JsonWriter writer, Person person, JsonSerializerOptions options)
{
var name = person.FirstName + " " + person.LastName;
var age = DateTime.Now.Year - person.Birthday.Year;

writer.WriteStartObject();
writer.WriteString(nameof(name), name);
writer.WriteNumber(nameof(age), age);
writer.WriteEndObject();
}
}

两者都需要实现。当我们的模型序列化为 JSON 时,将调用该方法,当 JSON 被反序列化为我们的模型时,将调用该方法。ReadWriteWriteRead

第 3 步:将属性添加到类

现在,我们既有了类又有了它的自定义 JSON 转换器,我们需要将 JSON converter 属性添加到我们的模型中。

[JsonConverter(typeof(PersonJsonConverter))]  
public record Person(string FirstName, string LastName, DateOnly Birthday);

第 4 步:添加控制器

我们将添加一个控制器来测试我们的自定义 JSON 转换器。

app.MapPost("/person", (Person person) =>  
{
return person;
})
.WithName("AddPerson")
.WithOpenApi();

这是一个 HTTP POST 端点。通过 HTTP 调用添加人员时,首先使用 JSON 转换器的方法将 JSON 转换为类。之后,HTTP 终端节点返回 ,然后使用 JSON 转换器的方法再次将其转换为 JSON。PersonReadPersonWrite

第 5 步:测试

现在,我们可以使用 HTTP 请求测试我们的设置。

将具有以下参数的人员发布到 :/person

{  
"firstName": "Alice",
"lastName": "Hills",
"birthday": "1992-11-04"
}

HTTP 终端节点返回:

{  
"name": "Alice Hills",
"age": 32
}

我们发布一个包含名字、姓氏和生日的人,我们的 HTTP 端点返回全名和人的年龄。

您可以编写自己的 JSON 转换器来满足客户的要求,同时保持模型的整洁。

源代码获取:公众号回复消息【code:50923

如果你喜欢我的文章,请给我一个赞!谢谢

架构师老卢
资深软件架构师, 分享编程、软件设计经验, 教授前沿技术, 分享技术资源(每天发布电子书),每天进步一点点...
 最新文章