C# 有没有办法将一个类的 JSON 字符串反序列化到另一个类中?

问题描述 投票:0回答:1

我的程序有一个包含许多属性的类,用于存储用户项目的所有设置和信息,如下所示:

Class Config{
    public bool EnableYoutube { get; set; }= true;
    public bool EnableFacebook { get; set; }= true;
}

当用户保存时,我将此类序列化为 JSON 并将其保存到文本文件中。相反,当用户加载项目时,我读取文本文件并反序列化 JSON 以恢复项目的设置和信息。

现在我有一个棘手的问题:当我更新软件时,我可能会添加一些功能,需要修改或添加新的属性到这个类,像这样:

Class Config{
    public bool EnableYoutube { get; set; }= true;
    
    public bool EnableTiktok { get; set; }= true;
}

当用户更新软件然后加载项目时,这个JSON的反序列化失败,因为两个类的结构发生了变化。

稍后我可能会使用数据库,但现在项目进度很紧,我无法做出太大的切换。也许有更好的方法将设置保存在纯文本文件中?我该如何解决这个问题?

c# json
1个回答
0
投票

这将取决于您所做的更改以及如何配置序列化器。

System.text.json 默认情况下应该是相当宽容的,如果有额外的属性,它们应该被忽略。据我所知,你的例子应该可以工作。但为这样的事情编写单元测试是一个非常好的主意:

public class Config1
{
    public bool EnableYoutube { get; set; } = true;
    public bool EnableFacebook { get; set; } = true;
}
public class Config2
{
    public bool EnableYoutube { get; set; } = true;
    public bool EnableTiktok { get; set; } = true;
}
[Test]
public void SerializeTest()
{
    var sut = new Config1() { };
    var str = JsonSerializer.Serialize(sut);
    Assert.DoesNotThrow(() => JsonSerializer.Deserialize<Config2>(str));
}

一些建议:

  1. 格式的版本号和其他元数据可能有用。请注意,这可能不应该是序列化数据的一部分,但可能是文件名或扩展名的一部分。
  2. 使用仅用于序列化的专用类,如果您进行较大的结构更改,这可以让您维护配置类的多个版本,并编写自定义代码来转换为最新格式。此类类型有时称为“数据传输对象”,即“ConfigDTO”确实将它们与包含逻辑的类区分开来。
  3. 使用属性,如
    [JsonRequired]
    [JsonPropertyName(...)]
    来告诉序列化器如何处理属性。
  4. 确保非必需属性具有默认值。
  5. 您可以使用 zip 存档将多条数据存储在一个文件中。这可以帮助处理包含异构数据的“项目”类型文件,同时仍然允许相当容易的调试。

同时考虑向后兼容性(即新软件加载旧项目)和前向兼容性(即旧软件加载新项目)。如果尝试从较新版本加载文件,则简单地显示错误并不罕见。

将设置存储在纯文本文件中本身并不能解决向后兼容性问题,数据库也不能。无论您以何种方式存储数据,您都需要牢记并测试向后和/或向前兼容性。最佳方法将取决于确切的用例。

© www.soinside.com 2019 - 2024. All rights reserved.