[JSON.NET] Fehler beim Deserialisieren von Array

  • C#
  • .NET (FX) 3.0–3.5

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Fortender.

    [JSON.NET] Fehler beim Deserialisieren von Array

    Hallo,
    möchte ein Json Array ordentlich deserialisieren. Zum deserialisieren habe ich für den JsonDeserializer extra Klassen angelegt, die dem Schema des Json Strings entsprechen (jedenfalls denke/hoffe ich das).

    C#-Quellcode

    1. public class List {
    2. public const string RequestMethod = "GET";
    3. public const string RequestPath = "api/v1/bot/instances";
    4. public class Success {
    5. public class Instance {
    6. [JsonProperty("uuid")]
    7. public string Uuid { get; set; }
    8. [JsonProperty("nick")]
    9. public string Nick { get; set; }
    10. [JsonProperty("running")]
    11. public bool IsRunning { get; set; }
    12. [JsonProperty("mainInstance")]
    13. public bool IsMainInstance { get; set; }
    14. } //Instances
    15. [JsonProperty("instances")]
    16. public List<Instance> Instances { get; set; }
    17. } //Success
    18. } //List

    Was jetzt nicht Thema sein soll ist die Klassenverkapselung, die für Unwissende wahrscheinlich komisch aussieht. Da ich aber eine Lib schreiben möchte um eine API anzusteuern, habe ich absichtlich
    ein solches Format gewählt. Aber wie gesagt, das soll nicht das Thema sein.

    Das Schema sollte klar sein. 4 Eigenschaften in der Instance-Klasse und Success umgibt eine Instances-Eigenschaft welche das Array darstellen soll.
    Zu deserialisieren ist dieser String:

    Quellcode

    1. "[{\"uuid\":\"e76fd6a6-d2c8-42ff-ba06-077c7e487a19\",\"nick\":\"MusicBot 1\",\"running\":true,\"mainInstance\":true},
    2. {\"uuid\":\"0e4cf914-9222-4a78-a4fc-4ba145baf637\",\"nick\":\"MusicBot 2\",\"running\":true,\"mainInstance\":false}]"


    Ich bekomme allerdings einen Laufzeitfehler beim Deserialisieren.
    Fehler:
    Spoiler anzeigen


    Ein Ausnahmefehler des Typs "Newtonsoft.Json.JsonSerializationException" ist in Newtonsoft.Json.dll aufgetreten.

    Zusätzliche Informationen: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Sinusbot.JsonClasses.Instances.List+Success' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

    To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

    Path '', line 1, position 1.

    An der Stelle:

    C#-Quellcode

    1. return JsonConvert.DeserializeObject<List.Success>(JsonString);



    Das List<Instance> soll laut Json.Net ja kein Problem sein. Ich denke aber, dass durch meine Kapselung versucht wird das Array auf List.Success zu deserialisieren und nicht auf die List<Instance> Instances.

    Ich bin relativ neu was Json angeht. Nicht vergessen :whistling:

    MfG Tim

    Fortender schrieb:

    Zu deserialisieren ist dieser String
    Das ist ein Feldelement, da drumherum [] stehen, ist also Teil eines Ganzen.
    Wie sieht denn die komplette JSon-Datei aus?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Deinem Code nach zu urteilen, müsste dein JSON so aussehen:

    Quellcode

    1. {
    2. "instances":[
    3. {
    4. "uuid":"e76fd6a6-d2c8-42ff-ba06-077c7e487a19",
    5. "nick":"MusicBot 1",
    6. "running":true,
    7. "mainInstance":true
    8. },
    9. {
    10. "uuid":"0e4cf914-9222-4a78-a4fc-4ba145baf637",
    11. "nick":"MusicBot 2",
    12. "running":true,
    13. "mainInstance":false
    14. }
    15. ]
    16. }
    Den Json String bekomme ich als HttpWebResponse.
    Mir ist jetzt aber klar was hier das Problem ist. Der Entwickler hat bei seiner API-Dokumentation einen Fehler gemacht.
    Wenn er schreibt object[] und eingerückt darunter die member eines objects dann kann man das aus den anderen Fällen in der API
    nur so ableiten wie ich es vorhatte. Hier nochmal die API.

    Könnte ich dem Deserializer nicht einfach als Typ List<Instance> übergeben statt die ganze Klasse? Müsste der Deserializer verstehen. Probier
    ich sofort mal aus.

    Danke :)