2016-07-20 3 views
2

Я использую NodaTime на протяжении всего моего проекта в качестве замены стандартных классов BCL DateTime с потрясающими результатами.Использование Newtonsoft JToken.ToObject <T> to deserializeNodaTime Instant

Я хотел бы изгнать DateTime из моего проекта полностью. Я использую его только в одном месте - где я десериализую большой файл JSON, содержащий даты. Эти даты: всегда UTC и всегда, указанный в стандарте ISO 8601.

using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using Newtonsoft.Json.Schema; 

namespace Foo.Parsing 
{ 
public class Parser 
{ 
    JSchema schema; 
    JObject jsonObject; 

    public Parser(string jsonContent, string schemaString) 
    { 
     schema = JSchema.Parse(schemaString); 
     jsonObject = JObject.Parse(jsonContent); 
    } 

    public MyObject Parse() 
    { 
     return jsonObject.ToObject<MyObject>(); 
    } 
} 

public class MyObject 
{ 
    [JsonProperty(Required = Required.Always)] 
    public DateTime date { get; set; } 

    // A lot of other properties here. 
} 
} 

Это все работает очень хорошо, но в данный момент я должен использовать Instant.FromDateTimeUtc(myObject.date); для преобразования DateTimes в Живом. Внутри MyObject меня DateTimes и если я пытаюсь изменить это Instant, я получаю следующее сообщение об ошибке:

Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.dll Additional information: Error converting value 2016/07/07 12:00:00 AM to type 'NodaTime.Instant'. Path 'date', line 4, position 37

Есть ли способ для меня, чтобы десериализации моего файла JSON в мое строго типизированном MyObject, с датами моих десериализаций напрямую to Instant вместо того, чтобы конвертировать DateTime?

+2

Вы используете пакет '' NodaTime.Serialization.JsonNet' '(https://www.nuget.org/packages/NodaTime.Serialization.JsonNet)? У этого есть конвертеры, которые должны помочь с этим. См. [Deserializing Noda Time's LocalDateTime с JSON.NET] (http://stackoverflow.com/q/21050002/10263), чтобы узнать подробности об этом. –

+0

Спасибо, что сделал мне еще один шаг, хотя теперь я получаю сообщение об ошибке «Неожиданный токен, разбор Мгновенный. Ожидаемая строка, дата». Как JObject знает, что это дата? Я замечаю, что когда я устанавливаю MyObject.date как строку, а не Instant/DateTime, он возвращается в другом (не ISO) формате, поэтому что-то в JObject.Parse, кажется, распознает формат как дату ... – Ivan

ответ

3

согласно Noda Time User Guide:

Если вы все еще получаете "Неожиданный маркер ..." сообщения, а затем, вероятно, вы изменили настройку DateParseHandling. Звонок ConfigureForNodaTime установит это на DateParseHandling.None, и его следует оставить таким же образом.

Обратите внимание, что это хорошо работает с JsonConvert.SerializeObject и JsonConvert.DeserializeObject классов, так как они принимают параметр JsonSettings, который также может быть установлен с помощью JsonConvert.DefaultSettings. Here is a live demo using this approach.

Однако, если вы используете API-интерфейсы JObject, есть одна небольшая проблема. JObject.Parse не имеет возможности принять параметр параметров, и по умолчанию у вас не будет DateParseHandling.None, который требуется на этом этапе. Решением этого является использование JsonTextReader и хорошо описано in this StackOverflow answer.

+0

Нет , Я вызываю Configure прямо перед тем, как я deserialize. Я попытался добавить «DateParseHandling.None» следующим образом. Еще нет кости: 'JsonSerializer Serializer = новый JsonSerializer();' ' serializer.ConfigureForNodaTime (DateTimeZoneProviders.Tzdb),' ' serializer.DateParseHandling = DateParseHandling.None;' ' вернуть jsonObject.ToObject (сериализатора); ' – Ivan

+0

См. Мой обновленный ответ. Я считаю, что последняя часть касается вашей текущей проблемы. –