使用嵌套对象和中间步骤进行反序列化
Posted
技术标签:
【中文标题】使用嵌套对象和中间步骤进行反序列化【英文标题】:Deserialization with nested object and in-between step 【发布时间】:2021-07-29 01:32:30 【问题描述】:我正在尝试使用 System.Text.Json JsonSerializer 序列化/反序列化对象。 我的容器对象是一个“LicenseFile”,其中包含一个“License”对象以及一个 byte[] 数字签名。
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)
感谢您的任何建议!
【问题讨论】:
System.Text.Json.JsonSerializer
已经将byte []
数组序列化为 Base64 字符串,请参阅The JSON value could not be converted to System.Byte[]
。但是为什么需要将License
转换为Base64?它不像 Base64 编码实际上提供任何有意义的加密、混淆或奇偶校验。
我使用 Base64 只是为了防止偶然的可读性,而不是为了任何安全性。主要对如何在序列化请求和最终结果之间介入的一般技术感兴趣。
【参考方案1】:
我推荐:
-
专用 Dto;或
[JsonIgnore]
on 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"
【讨论】:
以上是关于使用嵌套对象和中间步骤进行反序列化的主要内容,如果未能解决你的问题,请参考以下文章