Avatar billede chrisrj Forsker
21. november 2022 - 12:58 Der er 9 kommentarer og
1 løsning

Tjek for NULL i JSON

Hejsa

Jeg har en JSON, som kan have forskelligheder, og derfor er jeg nødt til at tjekke for NULL i den.

Det fleste steder går det fint, men eet sted driller.

En normal JSON indeholder categories, og jeg skal have fat i entekst. Det virker fint.
"{
"transactions": [ {
...
...
...
"categories": [
                {
                    "id": "184",
                    "names": {
                        "da": "dktekst",
                        "en": "entekst",
                        "fi": "fitekst",
                        "no": "notekst",
                        "sv": "svtekst"
                    },
                    "parentId": "20",
                    "setId": "pfm",
                    "score": 95.845
                },
...
...
...
],
...
...
...
}]"

Men den kan også se således ud:
"{
"transactions": [ {
...
...
...

            "categories": [],
...
...
...
}]"

Og så crasher min kode. :-/

if ((string)transactionsjson[transactions][j][categories][0] != null) // doesn't work

Jeg tror jeg har prøvet ca. 517 varianter uden at finde en løsning der virker. Jeg vil VIRKELIG gerne undgå en try/catch, da det er mega grimt at se på. :p

Jeg bruger .net 6 og newtonsoft.json 13.0.1, hvis det skulle betyde noget.
Avatar billede arne_v Ekspert
21. november 2022 - 13:57 #1
Du skal vel teste på længden af arayet.
Avatar billede chrisrj Forsker
21. november 2022 - 14:01 #2
Jah, men hvordan? :)
Avatar billede chrisrj Forsker
21. november 2022 - 14:06 #3
Hvis jeg gør sådan her:
if ((int)transactionsjson[transactions][j][categories][0].Count() > 0)

Får jeg en "Index was out of range" fejl
Avatar billede chrisrj Forsker
21. november 2022 - 14:20 #4
Nui, det hjælper sørme hvis man fjerne [0] ! Who knew? :D


if ((int)transactionsjson[transactions][j][categories].Count() > 0)


Tak for at lede mig på rette vej! :D
Avatar billede arne_v Ekspert
21. november 2022 - 14:41 #5
Det er jo ikke helt ulogisk.

Hvad gør den med:

"categories": []

Det virker meget logisk at den laver et array eller en List med ingen elementer.

Og så skal man teste på om der ingen elementer er.

[0] henter første element som altså ikke er der og derfor giver en fejl.
Avatar billede chrisrj Forsker
21. november 2022 - 14:43 #6
Yup. Jeg var nok bare weekendstræt siden jeg ikke kunne se det. :D
Avatar billede arne_v Ekspert
21. november 2022 - 14:48 #7
Jeg kan se at du deserialiserer til et objekt træ (af Dictionary og List).

Hvis det var muligt at deserialisere til en type fast klasse, så ville det give lidt mere kontrol med tingere (inkl. bedre IDE support). Men jeg ved ikke om dine data kan det.
Avatar billede chrisrj Forsker
21. november 2022 - 15:28 #8
Data bliver smidt ned i et helt almineligt kedeligt array, så ingen fancy klasse struktur at lege med, desværre. :)
Avatar billede arne_v Ekspert
21. november 2022 - 17:32 #9
Lad mig prøve at illustere forskellen.

test.json:


{ "transactions": [ { "txid": 1, "categories": [ { "catid": 1001, "names": { "da": "datekst", "en": "entekst" } } ] }, { "txid": 2, "categories": [ ] } ] }


Objekt træ:


using System;
using System.IO;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            JObject data = (JObject)JsonConvert.DeserializeObject(File.ReadAllText("/work/test.json"));
            foreach(JObject tx in data["transactions"])
            {
                Console.WriteLine((int)tx["txid"]);
                foreach(JObject cat in (JArray)tx["categories"])
                {
                    Console.WriteLine("  " + (int)cat["catid"]);
                    JObject nam = (JObject)cat["names"];
                    Console.WriteLine("    " + (string)nam["da"]);
                    Console.WriteLine("    " + (string)nam["en"]);
                }
            }
            Console.ReadKey();
        }
    }
}


Type sikre klasser:


using System;
using System.Collections.Generic;
using System.IO;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace E
{
    public class Names
    {
        public string Da { get; set; }
        public string En { get; set; }
    }
    public class Category
    {
        public int CatId { get; set; }
        public Names Names { get; set; }
    }
    public class Transaction
    {
        public int TxId { get; set; }
        public List<Category> Categories { get; set; }
    }
    public class Data
    {
        public List<Transaction> Transactions { get; set; }
    }
    public class Program
    {
       
        public static void Main(string[] args)
        {
            Data data = JsonConvert.DeserializeObject<Data>(File.ReadAllText("/work/test.json"));
            foreach(Transaction tx in data.Transactions)
            {
                Console.WriteLine(tx.TxId);
                foreach(Category cat in tx.Categories)
                {
                    Console.WriteLine("  " + cat.CatId);
                    Names nam = cat.Names;
                    Console.WriteLine("    " + nam.Da);
                    Console.WriteLine("    " + nam.En);
                }
            }
            Console.ReadKey();
        }
    }
}
Avatar billede chrisrj Forsker
21. november 2022 - 18:42 #10
Det er meget fint, at du gerne vil hjælpe med at lave vores system bedre. Al ære og respekt for det. :)

Når det er så er sagt, så er problemet desværre, at vi henter data fra forskellige dataleverandører, og de er, naturligvis, forskellige.
Så vi har altså ikke mulighed for at lave een fast struktur. Og der er for mange til at vi kan lave en for hver(yay, tidspres).
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester