2010-03-06 17 views
10

Ich habe eine abgeflachte JSON:Kann Json.NET eine abgeflachte JSON-Zeichenfolge mit Punktnotation deserialisieren?

{ 
    "CaseName" : "John Doe v. State", 
    "CaseDate" : "<some date>", 
    "Client.FirstName" : "John", 
    "Client.LastName" : "Doe", 
    "Client.Email" : "[email protected]" 
    etc... 
} 

Ich will es diese Einheit zurück deserialisieren:

public class Case() 
{ 
    public string CaseName { get; set; } 
    public string CaseDate { get; set; } 
    public Client Client { get; set; } 
} 

wo Client.FirstName, Client.LastName und Client.Email sind Objekte im Client Objekt. Kann Json.NET verwendet werden, um die Punktnotation zu analysieren und diese Entität korrekt zu deserialisieren? Derzeit, unter Verwendung der Standardeinstellungen, sagt es mir, dass Client.FirstName keine Eigenschaft in Typ Case ist.

+0

Das ist nicht JSON. – ChaosPandion

+0

Ich habe es vereinfacht, um es lesbarer zu machen, aber ich habe es so modifiziert, dass es jetzt JSON ist. –

+0

um den Kommentar von ChaosPandion zu erweitern - der Standardweg repräsentiert, dass geschachtelte Daten (der Client) in Json eher wie {"CaseName": "John Doe v.State", "CaseDate": "", "Client" {" FirstName ":" John "," LastName ":" Doe "}} Wenn es möglich ist, den ausgegebenen Json stattdessen zu ändern, wäre das viel schneller als @ CasperOne's sln. Hängt davon ab, ob Sie die Serialisierung kontrollieren können? – MemeDeveloper

Antwort

5

Ja, Sie können. Sie würden eine Klasse von JsonConverter ableiten und die CanConvert-Methode überschreiben, um anzuzeigen, dass Sie den Client-Typ konvertieren können.

Dann überschreiben Sie die Methoden ReadJson und WriteJson, um die Felder des JSON-Literals zu lesen und zu schreiben.

Für einen JSON wörtlichen wie dieser, ist es mehr als wahrscheinlich, dass Sie eine JsonConverter für die Case Typ erstellen müssen, wie Sie bei der Serialisierung alle Eigenschaften des Client Objekt müssen zwischenzuspeichern, bis Sie genügend Informationen haben, um tatsächlich zu schaffen die Client Instanz.

Dann würden Sie die Add Methode auf der von den Converters property auf der JsonSerializer Instanz ausgesetzt JsonConverterCollection Instanz rufen Sie verwenden Ihre Serialisierung/Deserialisierung auszuführen.

Beachten Sie, dass, wenn Sie dies für eine Reihe von verschiedenen Klassen tun müssen, um die auf diese Weise dargestellt werden können, dann können Sie einJsonConverter Implementierung schreiben, und haben es auf dem Grundstück für ein Attribut scannen. Wenn die Eigenschaft das Attribut besitzt und ein anderes Objekt mit Eigenschaften verfügbar macht, würde es erwarten, die Punktnotation zu lesen/schreiben.

Es sollte beachtet werden, dass es sehr ungewöhnlich ist, wenn Sie die Punktnotation für den Bezeichner verwenden. Wenn möglich, auf der Seite, die JSON wörtlichen baut, sollte es es auf diese Weise tun:

{ 
    CaseName: "John Doe v. State", 
    CaseDate: "<some date>", 
    Client: 
    { 
     FirstName: "John", 
     LastName: "Doe", 
     Email: "[email protected]" 
    } 
} 

Aber das ist vorausgesetzt, dass Sie die Kontrolle über diesem Zweck haben. Wenn Sie das nicht tun, können Sie nicht viel tun.

Wenn Sie die Kontrolle haben, würde das Konstruieren Ihrer JSON-Literale auf diese Weise die Notwendigkeit einer benutzerdefinierten Implementierung JsonConverter negieren.

+1

Ja, ich würde es vorziehen, es auf der Seite des Absenders (ExtJS) richtig zu konvertieren, aber ich bin mir nicht sicher, ob das noch möglich ist. Die von Ihnen bereitgestellte Lösung ist praktikabel, aber angesichts der Anzahl der Entitäten und der Komplexität meines Objektdiagramms zu viel Arbeit. Ich hatte auf ein einfaches Flag oder einen allgemeineren JsonConverter gehofft, der für alle Punktnotationseigenschaften gelten würde. –

+1

@Daniel T .: Leider ist der JSON nicht Standard, weshalb Json.NET Probleme damit hat. Allerdings habe ich der Antwort einen Absatz hinzugefügt, um anzugeben, wie Sie * eine * JsonConverter-Implementierung schreiben können, kombiniert mit einem Attribut, um es zu veranlassen, die Punktschreibweise zu lesen/schreiben, wenn sie erwartet wird. – casperOne

0

Obwohl nur die Hälfte Problem (dh nicht mit der Tatsache, Ihr Objekt zu helfen hat abgeflacht)

Sie mit Punktnotation in eine sehr quick and dirty Art und Weise mit einem einfachen umgehen können

MyTargetClass retVal 
= JsonConvert.DeserializeObject<MyTargetClass>(jsonAsString.Replace(".", "_")); 

In Kombination mit geeigneten "_" Eigenschaftsnamen auf der MyTargetClass z

public class MyTargetClass 
{ 
    public string CaseName {get; set;} 
    public DateTime CaseDate {get; set;} 
    public string Client_FirstName {get; set;} 

    //Other Properties 
} 
Verwandte Themen