Анализ продолжительности ISO с помощью JSON.Net

У меня есть проект веб-API со следующими настройками в Global.asax.cs:

var serializerSettings = new JsonSerializerSettings
    {
        DateFormatHandling = DateFormatHandling.IsoDateFormat, 
        DateTimeZoneHandling = DateTimeZoneHandling.Utc
    };

serializerSettings.Converters.Add(new IsoDateTimeConverter());

var jsonFormatter = new JsonMediaTypeFormatter { SerializerSettings = serializerSettings };
jsonFormatter.MediaTypeMappings.Add(GlobalConfiguration.Configuration.Formatters[0].MediaTypeMappings[0]);

GlobalConfiguration.Configuration.Formatters[0] = jsonFormatter;

WebApiConfig.Register(GlobalConfiguration.Configuration);

Несмотря на все это, Json.Net не может разобрать длительность ISO.

Он выдает эту ошибку:

Значение преобразования ошибок "2007-03-01T13: 00: 00Z/2008-05-11T15: 30: 00Z" на введите "System.TimeSpan".

Я использую Json.Net v4.5.

Я пробовал разные значения, такие как "P1M" и другие, перечисленные на странице wiki, без везения.

Итак, вопрос:

  • Я что-то пропустил?
  • Или мне нужно написать какой-то пользовательский форматтер?

Ответ 1

Я столкнулся с той же проблемой и теперь использую этот настраиваемый конвертер для преобразования .NET TimeSpans в строки продолжительности ISO 8601.

public class TimeSpanConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var ts = (TimeSpan) value;
        var tsString = XmlConvert.ToString(ts);
        serializer.Serialize(writer, tsString);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        var value = serializer.Deserialize<String>(reader);
        return XmlConvert.ToTimeSpan(value);
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof (TimeSpan) || objectType == typeof (TimeSpan?);
    }
}