-1

I am a novice in C# and I am having issues reading a JSON file. The JSON file follows this format:

{
  "info": {
    "year": 2020,
    "version": "1.0",
    "description": "fake description",
    "date_created": "2020-04-31T20:32:11.8958473Z"
  },
  "licenses": [
    {
      "name": "fake name",
      "id": 2020
    }
  ],
  "images": [
    {
      "id": 1,
      "width": 1280,
      "height": 720,
      "filename": "filename1.jpeg",
      "license": 1
    },
    {
      "id": 2,
      "width": 1280,
      "height": 720,
      "filename": "filename2.jpeg",
      "license": 2
    },
    ...

For now I am trying to read the Images section in the JSON file. Here is my class for it:

public class Images    
{
    [JsonProperty("id")]
    public int id { get; set; }
    [JsonProperty("width")] 
    public int width { get; set; } 
    [JsonProperty("height")] 
    public int height { get; set; } 
    [JsonProperty("filename")]
    public string filename { get; set; } 
    [JsonProperty("license")]
    public int license { get; set; } 
}

public class Image_json
{
    [JsonProperty("images")]
    public Image Image_json { get; set; }
}

In my main class, I try deserializing it here:

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


using Newtonsoft.Json;

namespace C__Playground
{
    public class read_json
    {
        static void Main(string[] args)
        {
            using (StreamReader r = new StreamReader("COCOExport.json"))
            {
                string json = r.ReadToEnd();
                var test1 = JsonConvert.DeserializeObject<List<Image_json>(json);
            }
        }
    }
}

When I try to run the program, I get this message:

Unhandled exception. Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[C__Playground.Image_jsonJson]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

I have been following this post here. I tried using the solution here but it returns empty or I receive a null error. Any insights?

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Tyler Oleson
  • 187
  • 1
  • 9
  • 1
    The linked "related" question [Cannot deserialize the current JSON object (e.g. {“name”:“value”}) into type 'System.Collections.Generic.List](https://stackoverflow.com/q/21358493/3744182) is a duplicate. Your root JSON value is an object not an array so you need to deserialize to `Image_json` not `List` like so: `JsonConvert.DeserializeObject(json);` – dbc Apr 01 '21 at 17:20
  • 1
    As I said in my post, I followed that solution and I receive this error: Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. – Tyler Oleson Apr 01 '21 at 17:24
  • The code shown in your question doesn't compile, see https://dotnetfiddle.net/i0fOGE: `Compilation error (line 39, col 23): 'Image_json': member names cannot be the same as their enclosing type`. The answer below shows how to fix compilation, so give that + the linked answer a try. If those don't work, please [edit] your question to share a [mcve] with code that we can compile that reproduces the exception. – dbc Apr 01 '21 at 17:27
  • Your model is completely incorrect. You need to fix your model, so that is reflects the structure of your JSON. – AussieJoe Apr 01 '21 at 17:33
  • 1
    fixed the example to include minimal reproducible example. – Tyler Oleson Apr 01 '21 at 17:35

2 Answers2

3

Your problem should be here:

public class Image_json
{
    [JsonProperty("images")]
    public Image_json Image_json { get; set; }
}

This property is of type Image_json, which is the same as the containing class. You need a collection of Images. Could be an array or a List<Images>.

public class Image_json
{
    [JsonProperty("images")]
    public List<Images> Image_json { get; set; }
}

BTW, the Images class should be called Image since it holds a single image, not a collection of them.

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
0

Please find below code.

Class Images:

public class Images    
{
    [JsonProperty("id")]
    public int id { get; set; }
    [JsonProperty("width")]
    public int width { get; set; }
    [JsonProperty("height")]
    public int height { get; set; }
    [JsonProperty("filename")]
    public string filename { get; set; }
    [JsonProperty("license")]
    public int license { get; set; }
}

class ImageJson:

 public class ImageJson
{
    [JsonProperty("images")]
    public List<Images> Image_json // We shoild use list of images
    {
        get; set;
    }
}

To test output:

using (StreamReader r = new StreamReader("COCOExport.json"))
    {
        string json = r.ReadToEnd();
        var test1 = JsonConvert.DeserializeObject<ImageJson>(json);

        foreach(var output in test1.Image_json)
        {
            Console.WriteLine(output.id);
            Console.WriteLine(output.width);
            Console.WriteLine(output.height);
            Console.WriteLine(output.filename);
            Console.WriteLine(output.license);
        }
        Console.ReadLine();
    }

It is alwasy good practice to use PascalCasing for Properties.

Ex:) [JsonProperty("id")] public int Id { get; set; } Please find solution here. Explained in a video https://www.youtube.com/watch?v=nHtdReIhvag

  • Please try to improve your answer so you explain why your solution is a solution and how it works. Do not link to any youtube channel that contains a video, instead try to explain everything on this platform in text form. – Markus Safar Apr 02 '21 at 11:41