尽管有转换器和JsonNumberHandlingOptions,但无法将字符串反序列化为int



我正在尝试反序列化以下JSON(一个带有单个条目的数组(:

[
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"birth_year": "19BBY",
"gender": "male"
}
]

进入此记录:

internal record class Character
{
public string Name { get; init; } = "";
[property: JsonPropertyName("birth_year")]
public double Birth { get; init; }
public int Height { get; init; }
[property: JsonPropertyName("mass")]
public int Weight { get; init; }
public GenderEnum Gender { get; init; }
}

使用以下JsonSerializerOptions设置:

var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString,
Converters =
{
new GenderEnumConverter(),
new BirthYearConverter(),
new MeasurementsConverter()
}
};

两个顶部转换器工作良好。当我添加MeasurementsConverter时,我会得到一个异常:

internal class MeasurementsConverter : JsonConverter<int>
{
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TryGetInt32(out int result) ? result : -1;
}
public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}

Read方法上引发异常:

System.InvalidOperationException:"无法将令牌类型"String"的值作为数字获取。">

当我使用以下两个表达式进行反序列化时:

string result = await File.ReadAllTextAsync("people.json");
List<Character> people = JsonSerializer.Deserialize<List<Character>>(result, options);

你能帮我理解MeasurementsConverter : JsonConverter<int>为什么忽略NumberHandling = JsonNumberHandling.AllowReadingFromString选项吗?

注意:此json是来自swapi.dev/api/people的示例。如果您了解api,则结果数组中至少有一个条目的weight属性值为"unknown"。因此,这个转换器。

根据Jon上面的评论,我可以通过显式使用reader对象的Utf8JsonReader.TokenType属性来避免触发异常。

Read((覆盖现在看起来是这样的:

public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if(reader.TokenType == JsonTokenType.String && options.NumberHandling == JsonNumberHandling.AllowReadingFromString)
{
return int.TryParse(reader.GetString(), out int result) ? result : -1;
}
return reader.GetInt32();
} 

最新更新