使用 System.Text.Json,我创建了一个自定义转换器来将整数值反序列化为 TimeSpan 值。 我的转换器的 CanConvert 方法被调用,但没有调用 Read 方法,我不明白为什么。 我有一个类似的转换器,可以将字符串值反序列化为枚举值,并且它工作正常。 这是一个测试台:
转换器:
/// <summary>
/// Convert a json value expressed as a time span in seconds to a TimeSpan.
/// </summary>
internal class IntToTimeSpanJsonConverter : JsonConverter<TimeSpan>
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsAssignableTo(typeof(TimeSpan));
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
int seconds = reader.GetInt32();
TimeSpan res = TimeSpan.FromSeconds(seconds);
return res;
}
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
=> throw new NotImplementedException();
}
这是使用 xUnit 和 Fluent Assertions 的测试用例:
public class IntToTimeSpanJsonConverter_Tests
{
private JsonSerializerOptions _defaultOptions;
public IntToTimeSpanJsonConverter_Tests()
=> _defaultOptions=new JsonSerializerOptions();
[Fact]
public void Read_ShouldReturnCorrectTimeSpan()
{
// Assign
string json = /*lang=json*/ @"{
""IntegerTimeProperty"" : 900
}";
TestResponseWithTimeSpanConverter expected = new()
{
IntergerTimeProperty=TimeSpan.FromSeconds(900)
};
// Act
TestResponseWithTimeSpanConverter? act = JsonSerializer.Deserialize<TestResponseWithTimeSpanConverter>(json, _defaultOptions);
// Assert
act.Should().BeEquivalentTo(expected);
}
}
以及反序列化的目标类:
public class TestResponseWithTimeSpanConverter
{
[JsonConverter(typeof(IntToTimeSpanJsonConverter))]
public TimeSpan IntergerTimeProperty { get; set; }
}
预期结果是 IntegerTimeProperty 的 TimeSpan 为 900 秒,但我没有收到异常,而是返回默认(TimeSpan)值。
我尝试直接在 JsonSerializerOptions 的转换器列表中添加转换器,并且我有相同的症状,但每种类型都会调用 CanConvert 。
看起来 JsonConverter 属性已被识别,但要么未使用,要么使用另一个默认转换器。 我检查了 JsonSerializationOptions 的 Converter 属性,它是空的。
我尝试跟踪 System.Text.Json 方法来比较此转换器与正在工作的其他枚举之间的跟踪,但它的复杂性使得操作不可能或需要大量时间来理解该过程。
问题是:有人知道为什么我的转换器的 Read 方法没有被调用吗?
🙄😅 就是这样@Sweeper...我现在为堆栈溢出中的所有永恒感到羞耻...你是对的,这不起作用的原因只是因为它由于拼写错误而没有找到该属性,所以,不使用转换器。
我想它此时仍然会扫描目标类的每个 JsonConvertAttribute 并调用 CanConvert 。 这导致我的分析混乱。
请将您的回复作为正式答案发布,以便我可以给您评分。