System.Text.Json JsonConverterAttribute 未调用

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

使用 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 方法没有被调用吗?

c# json-deserialization system.text.json
1个回答
0
投票

🙄😅 就是这样@Sweeper...我现在为堆栈溢出中的所有永恒感到羞耻...你是对的,这不起作用的原因只是因为它由于拼写错误而没有找到该属性,所以,不使用转换器。

我想它此时仍然会扫描目标类的每个 JsonConvertAttribute 并调用 CanConvert 。 这导致我的分析混乱。

请将您的回复作为正式答案发布,以便我可以给您评分。

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