0

I have a small test file I'm trying to work with to deserialize the data into a model. I've already this using tokens in NewtonSoft.JSON but would rather do this properly with a model.

Example JSON

[
    {
        "faction": "Britain",
        "id": "aa_barrage",
        "image": "aa_barrage.png",
        "import_id": "02",
        "kredits": 1,
        "rarity": "Standard",
        "set": "Base",
        "text": {
            "de-DE": "Die gewählte Lufteinheit muss sich zurückziehen. Gibt deinem HQ +2 Verteidigung.",
            "en-EN": "Target air unit must retreat. Give your HQ +2 defense.",
            "es-ES": "La unidad aérea seleccionada debe retirarse. Otorga un +2 de defensa a tu cuartel general.",
            "fr-FR": "L'unité aérienne visée doit battre en retraite. Confère +2 de défense à votre QG",
            "it-IT": "L'unità aerea bersaglio deve Ritirarsi. Dai al tuo QG +2 difesa.",
            "pl-PL": "Wybrana jednostka powietrzna musi się wycofać. Zapewnij swojemu sztabowi +2 do obrony.",
            "pt-BR": "A unidade aérea na mira deve recuar. Dê +2 de defesa ao seu QG.",
            "ru-RU": "Выбранный воздушный отряд должен отступить. Ваш штаб получает +2 к защите.",
            "zh-Hans": "使一个空军撤退,你的总部获得 +2 防御力。",
            "zh-Hant": "使一個空軍撤退,你的總部獲得 +2 防禦力。"
        },
        "title": {
            "de-DE": "FLAK-SPERRFEUER",
            "en-EN": "AA BARRAGE",
            "es-ES": "BOMBARDEO AA",
            "fr-FR": "BARRAGE AA",
            "it-IT": "CONTRAEREA",
            "pl-PL": "ZAPORA PRZECIWLOTNICZA",
            "pt-BR": "BARRAGEM AA",
            "ru-RU": "ЗЕНИТНЫЙ ОГОНЬ",
            "zh-Hans": "防空弹幕",
            "zh-Hant": "防空彈幕"
        },
        "type": "order"
    },
    {
        "faction": "Britain",
        "id": "active_sonar",
        "image": "active_sonar.png",
        "import_id": "fy",
        "kredits": 0,
        "rarity": "Elite",
        "set": "OnlySpawnable",
        "text": {
            "de-DE": "Setzt alle feindlichen Einheiten fest. Karten in der gegnerischen Hand kosten 3 mehr.",
            "en-EN": "Pin all enemy units. Increase cost of all cards in enemy hand by 3.",
            "es-ES": "Inmoviliza todas las unidades enemigas. Las cartas en la mano del enemigo cuestan 3 más.",
            "fr-FR": "Immobilise toutes les unités ennemies. Les cartes dans la main de l'ennemi coûtent 3 de plus.",
            "it-IT": "Blocca tutte le unità nemiche. Aumenta di 3 il costo delle carte nella mano del nemico.",
            "pl-PL": "Przyszpil wszystkie wrogie jednostki. Koszt kart w ręce przeciwnika wzrasta o 3.",
            "pt-BR": "Imobilize todas as unidades inimigas. Todas as cartas na mão do inimigo custam mais 3.",
            "ru-RU": "Блокирует все вражеские отряды. Карты в руке противника стоят на 3 больше.",
            "zh-Hans": "压制敌方所有单位。对手所有手牌花费 +3。",
            "zh-Hant": "壓制敵方所有單位。對手所有手牌花費 +3。"
        },
        "title": {
            "de-DE": "AKTIVES SONAR",
            "en-EN": "ACTIVE SONAR",
            "es-ES": "SONAR ACTIVO",
            "fr-FR": "SONAR ACTIF",
            "it-IT": "SONAR ATTIVO",
            "pl-PL": "AKTYWNY SONAR",
            "pt-BR": "SONAR ATIVO",
            "ru-RU": "АКТИВНЫЙ СОНАР",
            "zh-Hans": "主动声呐",
            "zh-Hant": "主動聲納"
        },
        "type": "order"
    }
]

The current code I have for this is the following:


Module Program
    Sub Main(args As String())
        
        dim json As string = File.ReadAllText("C:\Temp\cards.json")
        
        dim result As cards = JsonConvert.DeserializeObject(Of cards)(json)

    End Sub
End Module

Public Class cards
    
    public property cards as list(of card)
    
End Class
Public Class card
    
    public property faction as string
    public property id as string
    public property image as string
    public property import_id as string
    public property kredits as integer
    public property rarity as string
    <JsonProperty("set")>
    public property cardset as string
    public property type as string
    
End Class

I can deserialize just one of these on its own, however when I try and deserialize with both it fails due to the following:

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'json_deserialize_test.cards' 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.

I have tried changing my deserialization to:

dim result As cards = JsonConvert.DeserializeObject(Of List(Of cards))(json) 

but to no available, something that was mentioned in another question, can someone point me in the right direction here please, I feel like I've been looking at it too long and need another pair of eyes.

Lynchie
  • 1,077
  • 2
  • 20
  • 36
  • You missing classes for `text` and `title` wich must be included in `card` class. Create class called `text` with all following properties (`de-DE as string, en-EN as String, ...`) and same for `title`. You can create one class, because they are same, and put into `card` class those two. – nelek Dec 16 '21 at 16:25
  • @nelek when I've processed it individually that hasn't caused an issue? :/ – Lynchie Dec 16 '21 at 16:25
  • 2
    `Dim result = JsonConvert.DeserializeObject(Of List(Of card))(json)` -- You can use properties of type `Dictionary(Of String, String)` to deserialize the missing members (`text` and `title`). – Jimi Dec 16 '21 at 16:28
  • @Jimi so my literally mistake was just doing the cards class instead of the card class itself....crap – Lynchie Dec 16 '21 at 17:22
  • 1
    `text` and `title` should be dictionaries, e.g. `Public Property text As Dictionary(Of String, String)`. Also you need to deserialize to a `List(Of card)` not a `List(Of cards)`. In fact `cards` seems useless. See [How can I parse a JSON string that would cause illegal C# identifiers?](https://stackoverflow.com/a/24536564/3744182) and [Cannot deserialize the JSON array (e.g. `[1,2,3]`) into type ' ' because type requires JSON object (e.g. {"name":"value"}) to deserialize correctly](https://stackoverflow.com/q/22557559/3744182) which look, in combination, to be duplicates; agree? – dbc Dec 16 '21 at 17:30
  • 2
    Yes, your JSON is an array of objects. You were trying to deserialize to an object (or a list of the same objects) that contains a property that describes an array. – Jimi Dec 16 '21 at 17:31

0 Answers0