2016-07-20 7 views
2

Ich verwende NodaTime in meinem Projekt als Ersatz für die Standard-BCL Datetime-Klassen, mit erstaunlichen Ergebnissen deserializeNodaTime.Mit Newtonsoft JToken.ToObject <T> Sofort

Ich möchte DateTime komplett aus meinem Projekt verbannen. Ich benutze es nur an einer Stelle - wo ich eine große JSON-Datei deserialize, die Daten enthält. Diese Daten sind immer UTC und immer in ISO 8601-Format angegeben.

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. 
} 
} 

Das alles funktioniert sehr gut, aber im Moment habe ich Instant.FromDateTimeUtc(myObject.date); verwenden, um die Datetime Instant zu konvertieren. Innerhalb MyObject habe ich Datetime und wenn ich versuche, dies zu Sofortiger zu ändern, erhalte ich folgende Fehlermeldung:

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

Gibt es eine Möglichkeit für mich, meine JSON-Datei in meinem stark typisierte MyObject deserialisieren, mit meinen Terminen Deserialisieren direkt zu Instant, anstatt eine DateTime zu konvertieren?

+2

Verwenden Sie das ['NodaTime.Serialization.JsonNet'-Paket] (https://www.nuget.org/packages/NodaTime.Serialization.JsonNet)? Es hat Konverter, die dabei helfen sollen. Details zur Einrichtung finden Sie in [Deserializing of Noda Time LocalDateTime mit JSON.NET] (http://StackOverflow.com/q/21050002/10263). –

+0

Danke, das hat mich einen Schritt weiter gebracht, aber jetzt bekomme ich eine Fehlermeldung "Unerwartete Token Parsing Instant. Erwartete String, habe Datum." Woher weiß das JObject, dass es ein Date ist? Ich merke, wenn ich MyObject.date als String und nicht als Instant/DateTime setze, kommt es in einem anderen (nicht ISO-) Format zurück, also scheint etwas in JObject.Parse das Format als Datum zu erkennen ... – Ivan

Antwort

3

Per der Noda Time User Guide:

Wenn Sie noch immer "Unexpected Token ..." -Nachrichten, dann wahrscheinlich Sie haben die Einstellung DateParseHandling geändert. Der ConfigureForNodaTime Aufruf wird dies auf DateParseHandling.None setzen, und es sollte so belassen werden.

Beachten Sie, dass das funktioniert gut mit den JsonConvert.SerializeObject und JsonConvert.DeserializeObject Klassen, da sie einen JsonSettings Parameter akzeptieren, die auch über JsonConvert.DefaultSettings eingestellt werden kann. Here is a live demo using this approach.

Wenn Sie jedoch die JObject APIs verwenden, gibt es ein kleines Problem. JObject.Parse hat keine Möglichkeit, einen Einstellungsparameter zu übernehmen, und standardmäßig wird DateParseHandling.None in dieser Phase nicht benötigt. Die Lösung hierfür beinhaltet die Verwendung eines JsonTextReader und wird gut beschrieben in this StackOverflow answer.

+0

Nein , Rufe ich direkt vor der Deserialisierung Configure auf. Ich habe versucht, "DateParseHandling.None" wie folgt hinzuzufügen. keine Würfel noch: 'JsonSerializer Serializer = new JsonSerializer();' ' serializer.ConfigureForNodaTime (DateTimeZoneProviders.Tzdb);' ' serializer.DateParseHandling = DateParseHandling.None;' ' Rückkehr jsonObject.ToObject (Serializer); ' – Ivan

+0

Siehe meine aktualisierte Antwort. Ich glaube der letzte Teil adressiert dein aktuelles Problem. –

Verwandte Themen