System.Text.Json反序列化,其中有两个可能的属性名



是否有可能将JSON反序列化到一个属性名可能是两个值之一的类中?

例如,这两个json将反序列化为相同的属性:

var json1 = "{"A":5}";
var json2 = "{"B":5}";

我想也许我可以使用JsonPropertyName属性两次。

[JsonPropertyName("A")]
[JsonPropertyName("B")]
public int SomeInt { get; set; }

这是不允许的

然后我想,如果反序列化器找不到JsonPropertyName属性,它可能会寻找实际的属性名称。

[JsonPropertyName("A")]
public int B { get; set; }

但这也不行。

你可以有两个独立的属性,一个委托给另一个:

[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int A
{
get => B;
set => B = value;
}
[JsonPropertyName("B")]
public int B { get; set; }

缺点是在序列化时将写入。我最初认为您可以使用JsonIgnoreAttribute作为过时的属性,但这也会阻止它被反序列化:(如果您仅将其用于解析,则不太糟糕,但如果您也要序列化,则不太愉快。

另外,如果使用这两个参数解析JSON文件,最后设置的那个将胜出,这可能不是理想的。

我没有足够的声誉来评论Jon Skeet的回答,但是可以稍微修改一下,使用一个backing属性来避免两次写入。

[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int? A
{
get => B;
set => B = value;
}
private int? _b;
[JsonPropertyName("B")]
public int? B
{
get { return _b; } 
set
{
if (_b == null)
_b = value;
}
}

当对JSON进行反序列化时,我将使用一个可空的int,因为可能没有值。

如果必须使用int类型,则可以检查成员变量是否为default。缺点是如果你真的想让0代表0,如果第一个值是0并且它们都存在于文件中,那么它将被第二个值覆盖。

[JsonPropertyName("A")]
[Obsolete("Explain why here")]
public int A
{
get => B;
set => B = value;
}
private int _b;
[JsonPropertyName("B")]
public int B
{
get { return _b; } 
set
{
if (_b == default)
_b = value;
}
}

相关内容

  • 没有找到相关文章