c# - 使用嵌套对象和中间步骤进行反序列化
问题描述
我正在尝试使用 System.Text.Json JsonSerializer 序列化/反序列化对象。我的容器对象是一个“LicenseFile”,其中包含一个“License”对象以及一个字节[] 数字签名。
public class LicenseFile
{
public License License { get; set; }
public byte[] Signature { get; set; }
}
public class License
{
public string ProductName { get; set; }
public string ProductVersion { get; set; }
}
在序列化 LicenseFile 时,我还想先将 License 值转换为 JSON,然后再转换为 Base64。为此,我创建了一个自定义 JSON 转换器,例如
public class LicenseFileConverter : JsonConverter<LicenseFile>
{
public override void Write(Utf8JsonWriter writer, LicenseFile licenseFile, JsonSerializerOptions options)
{
writer.WriteStartObject();
var json = JsonSerializer.Serialize(licenseFile.License);
byte[] jsonBytes = new UTF8Encoding().GetBytes(json);
writer.WriteBase64String("License", jsonBytes);
writer.WriteBase64String("Signature", licenseFile.Signature);
writer.WriteEndObject();
writer.Flush();
}
}
我想得到一个像这样的 JSON 输出:
{
"License": "BASE64_OF_LICENSE_OBJECT_JSON'D",
"Signature": "BASE64_OF_SIGNATURE_BYTE[]"
}
我的问题:
- 这是一个好方法吗?我最好只使用辅助方法首先序列化值,base64 它们然后将它们写到文件中吗?
- 如何再次将 JSON 对象反序列化回对象(同时在途中对它们进行 de-base64 处理)
感谢您的任何建议!
解决方案
我建议:
- 一个专用的 Dto;或者
[JsonIgnore]
和License
辅助场;
例如:
public class LicenseFile
{
[JsonIgnore]
public License License { get; set; }
public string LicenseJson => JsonSerializer.Serialize(License); // Add base64 encoding if you wish
public byte[] Signature { get; set; }
}
或者
public class LicenseFileDto
{
public LicenseFileDto(LicenseFile license) {
License = JsonSerializer.Serialize(license.License);
Signature = license.Signature;
}
public string License { get; }
public byte[] Signature { get; }
}
测试
var l = new LicenseFile
{
License = new License(name: "X Y", validUntil: new DateTime(2021, 04, 22)),
Signature = new byte[] { 1, 2, 3 }
};
var json = JsonSerializer.Serialize(l,
options: new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
var dtoJson = JsonSerializer.Serialize(new LicenseFileDto(l),
options: new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(dtoJson);
// Documentation at:
// https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-character-encoding#serialize-all-characters
// says:
// Use the unsafe encoder only when it's known that the client will be interpreting the resulting payload as UTF-8 encoded JSON.
var prettyJson = JsonSerializer.Serialize(new LicenseFileDto(l),
options: new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
Console.WriteLine(prettyJson);
{
"LicenseJson": "{\u0022Name\u0022:\u0022X Y\u0022,\u0022ValidUntil\u0022:\u00222021-04-22T00:00:00\u0022}",
"Signature": "AQID"
}
{
"License": "{\u0022Name\u0022:\u0022X Y\u0022,\u0022ValidUntil\u0022:\u00222021-04-22T00:00:00\u0022}",
"Signature": "AQID"
}
{
"License": "{\"Name\":\"X Y\",\"ValidUntil\":\"2021-04-22T00:00:00\"}",
"Signature": "AQID"
}
推荐阅读
- python - 我如何只显示特定用户上传的产品?
- google-chrome - 有没有办法为开发者工具获取新的设备框架?
- css - 修复开发者端的浏览器颜色差异
- ios - 在从路径和基本 URL 创建 URL 的 iPad 上,如果基本 URL 位于存储设备上,则生成的 URL 会丢弃基本 URL 的最后一个组成部分
- matlab - 在matlab中使用shadedErrorBar时不能使用默认颜色以外的颜色
- c# - 如何使用 JsonWebTokenHandler web api 创建 JWT 身份验证令牌?
- wordpress - Woocommerce 插件导致服务器过载
- django - 服务器记录了 200 的 HTTP 状态代码,但 Chrome HAR 显示 403 - HTTP 状态代码可以更改吗?
- flutter - 如何在注册按钮颤动中使用 CircularProgressIndicator
- angular - 如何避免这些方法的执行顺序?(角度)