Значение доступа в JsonConverter.CanConvert () - PullRequest
0 голосов
/ 09 апреля 2020

Можно ли преобразовать string в TimeSpan объект, используя пользовательский JsonConverter, но он может преобразовываться только тогда, когда строка имеет формат "hh:mm:ss"?

У меня есть рассмотрел создание пользовательского JsonConverter, но метод CanConvert() принимает только объект Type, поэтому нет способа вернуть false, если строка не в формате "hh:mm:ss".

1 Ответ

0 голосов
/ 10 апреля 2020

Вы правы, что CanConvert имеет дело только с типами, и поэтому вы не можете настроить преобразователь на определенные значения c JSON. Тем не менее, вы сказали, что желаемое поведение заключается в том, что преобразование из строки в TimeSpan не выполняется, если формат не совсем соответствует hh:mm:ss, что я предполагаю, что вы ожидаете, что TimeSpan в вашем десериализованном объекте будет иметь значение по умолчанию ноль, правильно? В этом случае вы можете просто заставить метод ReadJson в конвертере делать то же самое, то есть возвращать значение по умолчанию TimeSpan, если формат не совсем совпадает:

public class TimeSpanConverter : JsonConverter<TimeSpan>
{
    public string TimeSpanFormat { get; set; } = @"hh\:mm\:ss";
    public TimeSpan DefaultTimeSpan { get; set; } = TimeSpan.Zero;

    public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string timeString = reader.GetString();
        if (TimeSpan.TryParseExact(timeString, TimeSpanFormat, CultureInfo.InvariantCulture, out TimeSpan timeSpan))
        {
            return timeSpan;
        }
        return DefaultTimeSpan;
    }

    public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(TimeSpanFormat));
    }
}

Вот короткая программа для продемонстрировать использование:

public static void Main(string[] args)
{
    string json = @"
    {
      ""TimeSpan1"": ""15:46:03"",
      ""TimeSpan2"": ""3:04""
    }";

    var options = new JsonSerializerOptions();
    options.Converters.Add(new TimeSpanConverter());
    var foo = JsonSerializer.Deserialize<Foo>(json, options);
    Console.WriteLine(foo.TimeSpan1.ToString(@"hh\:mm\:ss"));
    Console.WriteLine(foo.TimeSpan2.ToString(@"hh\:mm\:ss"));
}

public class Foo
{
    public TimeSpan TimeSpan1 { get; set; }
    public TimeSpan TimeSpan2 { get; set; }
}

Вывод:

15:46:03
00:00:00
...