JSON mit ""Namespace.Irgendwas": bool" deserialisieren

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von DanCooper.

    JSON mit ""Namespace.Irgendwas": bool" deserialisieren

    Hallo miteinander

    kann mir mal jemand sagen wie ich solch ein JSON deserialisieren kann?
    Ich kapiers nicht...

    Quellcode

    1. {
    2. "id": 0,
    3. "jsonrpc": "2.0",
    4. "result": {
    5. "Library.IsScanningVideo": false,
    6. "System.ScreenSaverActive": true
    7. }
    8. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DanCooper“ ()

    DanCooper schrieb:

    deserialisieren
    mit einem JSon-Deserialisator, gugst Du hier.
    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!
    Das ist mir klar :)

    Ich kriege das auch mit IsScanningVideo": false auf die Reihe, aber ich verstehe nicht wie es mit Library.IsScanningVideo": false geht.
    Ich kann ja nicht einfach das hier nutzen:

    C#-Quellcode

    1. namespace XBMCRPC.XBMC
    2. {
    3. public class GetInfoBooleansResponse
    4. {
    5. public bool Library.IsScanningVideo { get; set; }
    6. public bool System.ScreenSaverActive { get; set; }
    7. }
    8. }
    Dafür gibts Attribute (sofern du JSON.NET verwendest, wozu ich dir natürlich rate).
    Folgendes über die Variable (z.B. LibraryIsScanningVideo) schreiben: [JsonProperty(PropertyName = "Library.IsScanningVideo")]

    DanCooper schrieb:

    Das ist mir klar
    Trottzdem hast Du das Problem falsch beschrieben. :/
    Gugst Du auch hier.
    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!

    Rinecamo schrieb:

    Dafür gibts Attribute (sofern du JSON.NET verwendest, wozu ich dir natürlich rate).
    Folgendes über die Variable (z.B. LibraryIsScanningVideo) schreiben: [JsonProperty(PropertyName = "Library.IsScanningVideo")]


    Nein, wir verwenden Newtonsoft.Json.
    Geht das damit auch irgendwie? Oder kannst du mir das richtige Stichwort (Attribute?) nennen. mit dem ich Google fragen könnte?

    RodFromGermany schrieb:

    DanCooper schrieb:

    Das ist mir klar
    Trottzdem hast Du das Problem falsch beschrieben. :/
    Gugst Du auch hier.


    Mag sein, ich kenne leider die richtigen Fachausdrücke bei JSON nicht. Deshalb habe ich "solch ein JSON" geschrieben.
    Deinen Link kenne ich, dort gibt's aber auch nur einen nutzlosen Code zurück:

    C#-Quellcode

    1. public class Result
    2. {
    3. public bool __invalid_name__Library.IsScanningVideo { get; set; }
    4. public bool __invalid_name__System.ScreenSaverActive { get; set; }
    5. }

    DanCooper schrieb:

    Kodi
    Ist die fix oder mit anderen Werten oder noch völlig anders?
    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!

    Rinecamo schrieb:

    Dafür gibts Attribute (sofern du JSON.NET verwendest, wozu ich dir natürlich rate).
    Folgendes über die Variable (z.B. LibraryIsScanningVideo) schreiben: [JsonProperty(PropertyName = "Library.IsScanningVideo")]

    Danke, damit klappt es:

    C#-Quellcode

    1. namespace XBMCRPC.XBMC
    2. {
    3. public class GetInfoBooleansResponse
    4. {
    5. [Newtonsoft.Json.JsonProperty(PropertyName = "System.ScreenSaverActive")]
    6. public bool ScreenSaverActive { get; set; }
    7. }
    8. }


    Rinecamo schrieb:

    Newtonsoft.Json IST Json.NET.

    Danke, wieder was gelernt :)

    RodFromGermany schrieb:

    DanCooper schrieb:

    Kodi
    Ist die fix oder mit anderen Werten oder noch völlig anders?

    Es gibt da hunderte Namespaces und Klassen. Mit der Lösung von @Rinecamo funktioniert es aber erstmal. Wir benötigen zur Zeit nur Library.IsScanningVideo.

    Ich fände es aber trotzdem interessant zu wissen, wie man die Namespaces und Klassen sauber aufbauen würde. Falls du Lust hast, mir das Anhand von Library.IsScanningVideo zu erklären, dann fände ich das natürlich toll! Ich denke mal, dass man das mit relativ wenig Code umsetzen könnte. Aber ich von JSON und C# nicht so viel Ahnung, kann aber eigentlich gut von Beispielen ableiten ;)

    Hier findest du unseren bisherigen Code: GitHub
    Die Klasse wäre dann wohl GetInfoBooleansResponse und der Namespace Library

    Den grössten Teil haben wir bereits umgesetzt, eigentlich fehlt nur die komplette GetInfoBooleansResponse Klasse.

    Die Kodi JSON API ist hier dokumentiert: Link

    Rinecamo schrieb:

    Dafür gibts Attribute (sofern du JSON.NET verwendest, wozu ich dir natürlich rate).
    Folgendes über die Variable (z.B. LibraryIsScanningVideo) schreiben: [JsonProperty(PropertyName = "Library.IsScanningVideo")]


    Hallo Rinecamo

    ich wende mich nochmals an dich, da du mir Sicherheit auch hierbei weiterhelfen kannst.
    Hab nochmals ein ziemlich ähnliches Problem mit Enum. Ich muss diesmal is, true und false verwenden, was ebenfalls in einen String umgewandelt werden muss. Leider geht die Lösung mit EnumMember(Value) nicht:

    C#-Quellcode

    1. namespace XBMCRPC.List.Filter
    2. {
    3. public enum Operators
    4. {
    5. contains,
    6. doesnotcontain,
    7. [EnumMember(Value = "is")]
    8. Is,
    9. isnot,
    10. startswith,
    11. endswith,
    12. greaterthan,
    13. lessthan,
    14. after,
    15. before,
    16. inthelast,
    17. notinthelast,
    18. [EnumMember(Value="true")]
    19. True,
    20. [EnumMember(Value="false")]
    21. False,
    22. between,
    23. }
    24. }


    Kannst du mir auch hier auf die Sprünge helfen?
    Hast du nen passenden JSON-Ausschnitt aus dem du das Enum deserialisieren willst?
    Versuchen kannst du es mal mit: ​[JsonConverter(typeof(StringEnumConverter))] über dem ​public enum Operators

    Rinecamo schrieb:

    Hast du nen passenden JSON-Ausschnitt aus dem du das Enum deserialisieren willst?
    Versuchen kannst du es mal mit: [JsonConverter(typeof(StringEnumConverter))] über dem public enum Operators

    Wenn ich das direkt darüber schreibe kommt der Fehler Unerwartetes Zeichen "".:

    C#-Quellcode

    1. namespace XBMCRPC.List.Filter
    2. {
    3. [JsonConverter(typeof(StringEnumConverter))]
    4. public enum Operators
    5. {
    6. contains,
    7. doesnotcontain,
    8. [EnumMember(Value = "is")]
    9. Is,
    10. isnot,
    11. startswith,
    12. endswith,
    13. greaterthan,
    14. lessthan,
    15. after,
    16. before,
    17. inthelast,
    18. notinthelast,
    19. [EnumMember(Value="true")]
    20. True,
    21. [EnumMember(Value="false")]
    22. False,
    23. between,
    24. }
    25. }


    Genutzt werden die Enums hier:

    C#-Quellcode

    1. public class Rule
    2. {
    3. [Newtonsoft.Json.JsonProperty("operator")]
    4. public XBMCRPC.List.Filter.Operators Operator { get; set; }
    5. public object value { get; set; }


    is, true und false (klein geschrieben) kann ich ja in C# nicht direkt als Enum nutzen, weil das normale Operatoren(?) sind. Ich muss die also mit grossem Anfangsbuchstaben auflisten. Diese müssen aber danach für den JSON Request in Kleinbuchstaben umgewandelt werden. Aber ich glaube das hast du eh schon verstanden :D

    EDIT:
    Sorry, der Fehler Unerwartetes Zeichen "". kommt doch nicht. Funktionieren tut es aber trotzdem nicht.

    Hier hat einer das selbe Problem mit selbem Lösungsvorschlag, bei mir funktioniert das aber nicht. Is wird bei mir auch im Request immer noch mit grossem Anfangsbuchstaben eingesetzt.

    Edit 2:
    Moch jemand mit sogar exakt den gleichen Operatoren wie ich nutzen muss: Link
    Selbe Lösung, bei ihm scheints aber irgendwie zu gehen. Ich habe ebenfalls versucht den Converter direkt über die aufrufende Klasse zu setzen, geht bei mir aber auch nicht:

    C#-Quellcode

    1. [JsonProperty("operator")]
    2. [JsonConverter(typeof(StringEnumConverter))]
    3. public FilterOperator Operator { get; set; }


    EDIT 3:
    Ich hab mitlerweile rausgefunden, dass der Converter bereits gloabal gesetzt ist:

    Quellcode

    1. Serializer.Converters.Add(new StringEnumConverter());


    Entferne ich diesen, erhalte ich anstelle der Strings die Enum-Nummer. Der StringEnumConverter scheint also schonmal soweit zu funktionieren und es ist nicht nötig, dass ich diesen über die Klasse setze.
    Meiner Meinung nach funktioniert einfach der [EnumMember(Value="value")] Teil nicht...

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „DanCooper“ ()

    Ich weiß nicht, wo genau der Fehler liegt, aber ich würde es einfach mal so machen.
    So ist das Enum auch noch benutzbar und man muss sich nicht mit lowercase items rumschlagen.

    C#-Quellcode

    1. [JsonConverter(typeof(OperatorEnumConverter))]
    2. public enum Operators
    3. {
    4. Contains,
    5. DoesNotContain,
    6. Is,
    7. IsNot,
    8. StartsWith,
    9. EndsWith,
    10. GreaterThan,
    11. LessThan,
    12. After,
    13. Before,
    14. InTheLast,
    15. NotInTheLast,
    16. True,
    17. False,
    18. Between
    19. }
    20. public class OperatorEnumConverter : JsonConverter
    21. {
    22. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    23. {
    24. Operators weaponType = (Operators)value;
    25. writer.WriteValue(weaponType.ToString().ToLower());
    26. }
    27. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    28. {
    29. var values = Enum.GetNames(typeof(Operators));
    30. var enumValue = values.FirstOrDefault(v => v.ToLower().Equals(reader.Value.ToString()));
    31. Operators op;
    32. if (Enum.TryParse(enumValue, out op)) {
    33. return op;
    34. }
    35. return null;
    36. }
    37. public override bool CanConvert(Type objectType)
    38. {
    39. return objectType == typeof(string);
    40. }
    41. }

    Rinecamo schrieb:

    Ich weiß nicht, wo genau der Fehler liegt, aber ich würde es einfach mal so machen.
    So ist das Enum auch noch benutzbar und man muss sich nicht mit lowercase items rumschlagen.

    C#-Quellcode

    1. [JsonConverter(typeof(OperatorEnumConverter))]
    2. public enum Operators
    3. {
    4. Contains,
    5. DoesNotContain,
    6. Is,
    7. IsNot,
    8. StartsWith,
    9. EndsWith,
    10. GreaterThan,
    11. LessThan,
    12. After,
    13. Before,
    14. InTheLast,
    15. NotInTheLast,
    16. True,
    17. False,
    18. Between
    19. }
    20. public class OperatorEnumConverter : JsonConverter
    21. {
    22. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    23. {
    24. Operators weaponType = (Operators)value;
    25. writer.WriteValue(weaponType.ToString().ToLower());
    26. }
    27. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    28. {
    29. var values = Enum.GetNames(typeof(Operators));
    30. var enumValue = values.FirstOrDefault(v => v.ToLower().Equals(reader.Value.ToString()));
    31. Operators op;
    32. if (Enum.TryParse(enumValue, out op)) {
    33. return op;
    34. }
    35. return null;
    36. }
    37. public override bool CanConvert(Type objectType)
    38. {
    39. return objectType == typeof(string);
    40. }
    41. }


    Danke, das hat so ebenfalls wunderbar funktioniert!