2017-08-23 4 views
0

einige json gegeben, die wieDeserialisieren über JSON.NET mit Variable Name

sieht
{ 
    "id":"123_678", 
    "fs_123_678": 
    { 
    "title":"Apple Parts", 
    "data": 134 
    } 
} 

Ich mag würde es in den folgenden Klassen

public class Result 
{ 
    public string Id {get; set;} 
    public ResultInfo Info {get; set;} 
} 

public class ResultInfo 
{ 
    public string Title {get; set;} 
    public int Data {get; set;} 
} 

... aber das zweite Eigenschaft deserialisiert (fs_123_678) ist kein fester Name. Ich habe andere ähnliche Beiträge auf SO hier angeschaut, und die allgemeine Lösung ist die Verwendung einer IDictionary<string, MyPoco> jedoch, die nur funktioniert, wenn die variablen Daten nicht auf der Stammebene ist. Der Name der Eigenschaft ist 100% vorhersagbar, und ich könnte in Code beschreiben, was es für eine gegebene JSON-Antwort basierend auf Werten sein wird, die in der HTTP-Quellanforderung verwendet werden. Der Trick ist, wie lasse ich den JSON-Deseralizer in der Geschäftsregel um, wie es für diese gegebene Deserialisierung genannt wird? Ich brauche grundsätzlich etwas, das sich wie [JsonProperty(PropertyName = *insert logic here*)] verhält (was natürlich nicht möglich ist).

Was ist ein vernünftiger Weg, um dies zu erreichen, alle unter Beibehaltung der "for free" stark typisierte Deserialisierung des Rests des Objekts?

+0

Ich würde einen benutzerdefinierten Deserializer (JSON.NET hat einen tollen Artikel darüber auf ihrer Website) schreiben. –

+0

@SamAxe genial, ich suchte im Abschnitt "Serialisierung und Deserialisierung von JSON" (https://www.newtonsoft.com/json/help/html/SerializingJSON.htm) und ich sah nichts, das mir helfen würde - Aber vielleicht habe ich es verpasst? Haben Sie zufällig einen handlichen Dandy-Link? – ckittel

+0

Sie können '[JsonTypedExtensionData]' und 'TypeedExtensionDataConverter ' von [Wie ein Kindobjekt mit dynamischen (numerischen) Schlüsselnamen deserialisieren?] (Https://stackoverflow.com/a/40094403/3744182). Oder Sie könnten eine benutzerdefinierte ['JsonConverter'] (https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm) für 'Result' schreiben, wie zB in [this antwort] (https://stackoverflow.com/a/23017892/3744182) oder [dieser] (https://stackoverflow.com/a/30179162/3744182). – dbc

Antwort

1

Basierend auf den Links, die dbc in Kommentaren zur Verfügung gestellt, fand ich, dass diese Lösung funktioniert, aber offen für andere Vorschläge. Ich nehme grundsätzlich den gegenwärtigen Leserstrom und lade es als JObject dann das Original JProperty durch ein anderes, das den Namen hat, den mein Modell erwartet, ersetzend.

public class MyCustomResultConverter : JsonConverter 
{ 
    public override bool CanWrite => false; 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var obj = JObject.Load(reader); 
     var formData = obj.SelectToken("fs_" + obj.SelectToken("id").Value<string>()); 
     formData.Parent.Replace(new JProperty("info", formData)); 

     existingValue = existingValue ?? new FormActionResult(); 
     serializer.Populate(obj.CreateReader(), existingValue); 
     return existingValue; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(Result).GetTypeInfo().IsAssignableFrom(objectType); 
    } 
} 

[JsonConverter(typeof(MyCustomResultConverter))] 
public class Result 
{ 
    public string Id {get; set;} 
    public ResultInfo Info {get; set;} 
} 
Verwandte Themen