System.Text.Json JsonConverterAttribute не вызывается [закрыто]C#

Место общения программистов C#
Ответить
Anonymous
 System.Text.Json JsonConverterAttribute не вызывается [закрыто]

Сообщение Anonymous »

С помощью System.Text.Json я создал собственный преобразователь для десериализации целочисленного значения в значение TimeSpan. У моего конвертера вызывается метод CanConvert, а метод Read — нет, и я не понимаю почему. У меня есть аналогичный преобразователь для десериализации строкового значения в значение Enum, и он работает правильно. Вот тестовый стенд:
Преобразователь:

Код: Выделить всё

/// 
/// Convert a json value expressed as a time span in seconds to a TimeSpan.
/// 
internal class IntToTimeSpanJsonConverter : JsonConverter
{
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(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 распознается, но либо не используется, либо используется другой преобразователь по умолчанию. Я проверил свойство Converter JsonSerializationOptions, и оно пусто.
Я пытался отследить методы System.Text.Json, чтобы сравнить трассировку между этим преобразователем и другим перечислением, которое работает, но сложность делает операцию невозможной или потребуется много времени, чтобы понять процесс.
Вопрос: кто-нибудь знает, почему метод Read моего конвертера не вызывается?
Вопрос: кто-нибудь знает, почему метод Read моего конвертера не вызывается?
п>

Подробнее здесь: https://stackoverflow.com/questions/790 ... not-called
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»