Вы правы, что 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