myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » JSON Dynamic Property Deserialize
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

JSON Dynamic Property Deserialize

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster


Duesmannr ist offline

JSON Dynamic Property Deserialize

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mahlzeit,

mit Stackoverflow/Google und die SuFu hier, komme ich nicht weiter.

Ich erhalte ein dynamisches Json Objekt von einer Api.

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
{
   "container":{
      "mirror_1":{
         "links":[
            "https:\/\/google.de",
            "https:\/\/mycsharp.de"
         ],
         "backup":[
            [
               "https:\/\/google.de",
               "https:\/\/mycsharp.de"
            ]
         ]
      },
      "mirror_2":{
         "links":[
            "https:\/\/google.de",
            "https:\/\/mycsharp.de"
         ],
         "backup":[
            [
             "https:\/\/google.de",
             "https:\/\/mycsharp.de"
            ]
         ]
      }
   }
}

Dynamisch an dem JSON sind die Mirrors. Basierend auf der Anzahl kann 1 bis n vorkommen.
Also

Code:
1:
mirror_{n}

Ich weiß aber nicht wie ich das in Klassen deserialisieren soll.
In einem anderen Projekt konnte ich einfach ein Dictionary nehmen, funktioniert hier nicht.

Auch mit mit einem Custom DefaultContractResolver versucht wie hier beschrieben
 Stackoverflow
läuft es auch nicht.

So sehen die Klassen generiert aus

C#-Code:
public class Rootobject
    {
        public Container container { get; set; }
    }

    public class Container
    {
        public Mirror_1 mirror_1 { get; set; }
        public Mirror_2 mirror_2 { get; set; }
    }

    public class Mirror_1
    {
        public string[] links { get; set; }
        public string[][] backup { get; set; }
    }

    public class Mirror_2
    {
        public string[] links { get; set; }
        public string[][] backup { get; set; }
    }

Habt Ihr ggfs. Ansätze?

Grüße

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Duesmannr am 21.05.2020 12:39.

21.05.2020 12:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.224
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Da das Json hier in der Grundstruktur halt schon "suboptimal" besser gesagt beschissen ist bringt Dir das generierte Zeugs natürlich nichts.
Du wirst Dir wohl oder übel nen eigenen Visitor basteln müssen, der die Nodes anhand des Namens und der Nummer erkennt und dann parst.

Generisch ist hier nicht (ohne weiteres).

Da hat offenbar jemand ne API erstellt, der das nicht hätte tun sollen :-)
21.05.2020 12:59 Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die Response ist genau so gut, wie die "dokumentierte" Api..

Was meinst du denn explizit mit Visitor?
21.05.2020 13:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Palladin007 Palladin007 ist männlich
myCSharp.de-Mitglied

avatar-4140.png


Dabei seit: 03.02.2012
Beiträge: 1.311
Entwicklungsumgebung: Visual Studio 2019
Herkunft: NRW


Palladin007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich kenne nur Json.NET bzw. Newtonsoft.Json, aber da gibt's z.B. die  JObject-Klasse.
Damit kannst Du dein Json dann parsen und ungefähr so flexibel durchsuchen, wie es mit LINQ to XML möglich ist - ist vermutlich auch daran orientiert.

Was Abt genau meint, weiß ich auch nicht, aber mit JObject wäre dein Vorhaben auf jeden Fall möglich.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am 21.05.2020 14:15.

21.05.2020 14:15 Beiträge des Benutzers | zu Buddylist hinzufügen
Papst Papst ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.09.2014
Beiträge: 299
Entwicklungsumgebung: VS2017
Herkunft: Kassel


Papst ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du könntest das mit einem Dictionary machen.

C#-Code:
class Root {
public Dictionary<string, Mirror> Container { get; set; }
}
21.05.2020 14:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Auf JObject bin ich auch schon gekommen.

Habe jetzt eine Lösung, auch wenn ich die nicht wirklich schön finde.

Verzeiht mir die temporären Variablennamen, aber beim durchgehenden Debuggen, hatte ich keine Lust, jedesmal sinnvolle Namen zu nehmen.

C#-Code:
JObject objec = JObject.Parse(responseString);

JObject klgfds = (JObject)objec["container"]["mirror_1"];

String jkgfsd = klgfds.ToString(Formatting.None);

Mirror1 mirro1 = JsonConvert.DeserializeObject<Mirror1>(jkgfsd);

Das funktioniert so. Mirror1 ist das equivalent zu Mirror_1 wie im Startpost.
21.05.2020 14:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Papst:
Du könntest das mit einem Dictionary machen.

Nein, dass funktioniert leider nicht.
Der konvertiert das dann nicht. Und das Dictionary ist null.
21.05.2020 14:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.224
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Duesmannr:
Was meinst du denn explizit mit Visitor?

Im Fall von Newtonsoft.Json ein JsonConverter sowie das dazuhörige Attribute.

Damit kannst Du dann alle Nodes ermitteln, die mit Mirror_ beginnen und entsprechend manuell serialisieren.

So hast Du als Objekt eine saubere Liste, auch wenn die Json Response murks ist.

Wie gesagt; mit Standard-Zeugs kommst nicht weit - einfach, weil Du auch kein standardisiertes Ausgangsmaterial hast.

Dein Code so hilft Dir nicht, ausser Du willst wirklich n-Mirrors von Hand programmieren; wenn Du das willst, dann kannste Dir gleich einfach ne Container Klasse mit n-Mirror Properties bauen. Gewonnen hast also nichts.
Aber ich hab verstanden, dass Du das gar nicht willst.
21.05.2020 15:25 Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Abt:
Dein Code so hilft Dir nicht, ausser Du willst wirklich n-Mirrors von Hand programmieren; wenn Du das willst, dann kannste Dir gleich einfach ne Container Klasse mit n-Mirror Properties bauen. Gewonnen hast also nichts.
Aber ich hab verstanden, dass Du das gar nicht willst.

Naja nicht ganz, derzeit sieht es so aus.

C#-Code:
JObject responseObject = JObject.Parse(responseString);

            JObject containerObject = (JObject)responseObject["container"];

            List<Mirror> mirrors = new List<Mirror>();

            for (int i = 1; i < containerObject.Count + 1; i++)
            {
                JObject mirrorObject = (JObject)responseObject["container"][$"mirror_{i}"];

                Mirror mirror = JsonConvert.DeserializeObject<Mirror>(mirrorObject.ToString(Formatting.None));
                mirror.MirrorValue = i;

                mirrors.Add(mirror);
            }

Das ist aber auch keine Lösung und werde deinen Ansatz verfolgen, weil beim nächsten Endpunkt, dass gleiche Problem auftritt nur noch schlimmer.

Der Endpunkt holt mir die primären Informationen von allen Containern die existieren (keine Mirrors) und dabei steht das als Dokumentation:
Please note every Object child of the container-Node starts with a trailing _.

Im Endeffekt hätte ich dann pro Container eine eigene Klasse mit unterschiedlichen Namen.
21.05.2020 15:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.224
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mitm sauberen Serializer würde das so aussehen. Verstehe nicht, wieso Du nicht die Mittel von Json.NET nutzen magst...
Das Tooling von Json.NET deckt solche Fälle ja ab.

C#-Code:
        public override ContainerRecord ReadJson(JsonReader reader, Type objectType, ContainerRecord existingValue,
            bool hasExistingValue,
            JsonSerializer serializer)
        {
            var containerObject = JObject.Load(reader);
            for (int i = 1; i < containerObject.Count + 1; i++)
            {
                var mirrorObject = containerObject[$"mirror_{i}"].ToObject<MirrorRecord>();
                existingValue.Mirrors.Add(mirrorObject);
            }

             return existingValue;
        }

Ist natürlich sehr anfällig wenn man mal was anderes als nen Mirror in der Objektkiste hat..
21.05.2020 15:53 Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Abt:
Mitm sauberen Serializer würde das so aussehen. Verstehe nicht, wieso Du nicht die Mittel von Json.NET nutzen magst...

Zitat von Duesmannr:
Das ist aber auch keine Lösung und werde deinen Ansatz verfolgen[...]

Wie schon geschrieben, wollte ich ja auf die custom converter gehen.
Dein Code funktioniert fast. Du kannst beim override nicht die Parametertypen und den Rückgabetyp ändern. Noch sind wir nicht in C# 9.

Zitat von Abt:
Ist natürlich sehr anfällig wenn man mal was anderes als nen Mirror in der Objektkiste hat..

Das fange ich voher ab.
21.05.2020 16:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.224
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Duesmannr:
Du kannst beim override nicht die Parametertypen und den Rückgabetyp ändern.

MyContainerRecordConverter : JsonConverter<ContainerRecord>

Nimm Dir doch 2-3 Minuten Zeit ein Blick in die Doku zu werfen, statt nun irgendwas mit C# 9 zu vermischen ;-)
21.05.2020 16:15 Beiträge des Benutzers | zu Buddylist hinzufügen
Duesmannr Duesmannr ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.04.2017
Beiträge: 87
Entwicklungsumgebung: Visual Studio 2017/19
Herkunft: Münster

Themenstarter Thema begonnen von Duesmannr

Duesmannr ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Abt:
MyContainerRecordConverter : JsonConverter<ContainerRecord>

Stimmt.. vergessen.

Zitat von Abt:
Nimm Dir doch 2-3 Minuten Zeit ein Blick in die Doku zu werfen, statt nun irgendwas mit C# 9 zu vermischen ;-)

Wird auch noch gemacht, nachdem ich sehe, dass ich doch jetzt ziemlich oft die Custom Converter gebrauche.

Aber danke für die Hilfe.
21.05.2020 16:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Monate.
Der letzte Beitrag ist älter als 4 Monate.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 02.10.2020 01:24