【发布时间】:2021-12-07 12:13:14
【问题描述】:
我正在尝试更新已发布的 Json 可序列化类中的属性名称,因此我需要使其向后兼容。
public class myClass
{
//[JsonIgnore] - now old json files can't be read, so this won't work...
//[JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Error)] - didn't do anything
//[JsonProperty(nameof(NewName)] - throws error - "That already exists"
[Obselete("Use NewName instead")]
public List<string> OldName { get => newName; set => newName = value; }
public List<string> NewName { get; set; } = new List<string>();
}
我是这样使用它的:
[Test]
public void test()
{
var foo = new myClass()
{
OldName = { "test" },
};
var bar = JsonConvert.SerializeObject(foo);
var result = JsonConvert.DeserializeObject(bar, typeof(myClass));
}
当我查看 result.NewName 中的值时,我发现了这个列表:{"test", "test"},但我期望这个列表:{"test"}
期望的行为:
- 如果有人已经在他们的代码中使用 OldName,他们会收到过时警告
- 如果有人解析包含 OldName 的旧 json 文件,它会正确映射到 NewName
- 创建的新 json 文件使用 NewName,而在 json 文件中的任何位置都找不到 OldName
- 在任何情况下都不会将值反序列化两次并放入同一个列表中
你会如何做到这一点?
【问题讨论】:
-
我会为这种类型创建自定义转换器。
-
将 [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] 放在 OldName 和 NewName 上会阻止它附加到列表中,但不会阻止 Json 中的重复属性