0

I am getting the following error while deserializing. My coding blocks which I have been trying to deserialize are given below.

Error: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Subject' 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 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. Path 'Students[3].Subject'.....

JSON:

 {
   "Students":[
      {
         "Name":"Mr. X",
         "Class":"Ten",
         "Roll":5,
         "Subject":{
            "Name":"Math",
            "Marks":90
         }
      },
      {
         "Name":"Mr. Y",
         "Class":"Ten",
         "Roll":7,
         "Subject":{
            "Name":"Math",
            "Marks":80
         }
      },
      {
         "Name":"Mr. Z",
         "Class":"Ten",
         "Roll":8,
         "Subject":{
            "Name":"Math",
            "Marks":75
         }
      },
      {
         "Name":"Mr. A",
         "Class":"Ten",
         "Roll":1,
         "Subject":[
            {
               "Name":"Math",
               "Marks":95
            },
            {
               "Name":"English",
               "Marks":75
            }
         ]
      }
   ]
}

Program.cs:

Student_Collection students = new Student_Collection();

.....

string jsonString = await response.Content.ReadAsStringAsync();

  var settings = new JsonSerializerSettings
    {
      NullValueHandling = NullValueHandling.Ignore,
      MissingMemberHandling = MissingMemberHandling.Ignore
    };

// this the line where I am getting the error 
students = JsonConvert.DeserializeObject<Student_Collection>(jsonString, settings); 

Subject.cs:

class Subject
 {  
    public string Name { get; set; }
    public int Marks { get; set; }       
 }

Student.cs

class Student
 {  
    public string Name { get; set; }
    public string Class { get; set; }
    public int Roll { get; set; }
    public Subject Subject { get; set; }
 }

Student_Collection.cs

class Student_Collection
 {  
    public List<Student> students { get; set; }
 }
Salahuddin Ahmed
  • 4,854
  • 4
  • 14
  • 35
  • 2
    also post json that you are going to deserialize, most likely there is some syntax error in json. you can also verify json through some online tool. – sairfan Jul 26 '21 at 19:31
  • 1
    It sounds like the json you are trying to deserialize is actually a json array rather than an object containing an array. The deserializer is expecting an object {"students":[x,y,z]} containing the array rather than an array alone [x,y,z]. – user1934587390 Jul 26 '21 at 19:38
  • @sairfan, JSON data is just given in my post :) Thank you! – Salahuddin Ahmed Jul 26 '21 at 19:46
  • Inside Student_Collection change List to Student[] (array) – GH DevOps Jul 26 '21 at 19:51
  • @GHDevOps why it should help? – Guru Stron Jul 26 '21 at 19:52
  • 1
    Your error _"Path 'Students[3].Subject'".."_ reference item with 3d index in `Students` array while you have only 2 in example json. – Guru Stron Jul 26 '21 at 19:54
  • Try `public int Marks { get; set; }` – Charlieface Jul 26 '21 at 19:59
  • 1
    `Roll` and `Marks` should be int types https://dotnetfiddle.net/bSbBQR but either way, the json you provided isn't causing the issue... – Trevor Jul 26 '21 at 19:59
  • 1
    above json is working for me in my console app i was able to de-serialize and read properies from object `students.students` are you using `Newtonsoft.Json` which version? – sairfan Jul 26 '21 at 20:14
  • @GuruStron, I have updated the `JSON` in my post so that 3rd index in `Students` array can be seen. As said I have the error path `'Students[3].Subject'.....` – Salahuddin Ahmed Jul 26 '21 at 20:32
  • @sairfan, I have updated the `JSON` in my post and the error path is `Students[3].Subject`. Please look at the 3rd index in the `Students` array :) – Salahuddin Ahmed Jul 26 '21 at 20:37
  • 1
    JSON is inconsistent, in last element `Mr A` subject is an array but it should be an object, – sairfan Jul 26 '21 at 20:39
  • @zaggler, can you please check with the `JSON` again? Which I have just updated in my post. As said the error path is the 3rd index of the `Students` array. – Salahuddin Ahmed Jul 26 '21 at 20:41
  • @Charlieface and @zaggler, Roll and Marks type will be actually `int`; earlier which was set as `string` mistakenly in my post. Thank you! – Salahuddin Ahmed Jul 26 '21 at 20:54

1 Answers1

0

In this element Subject is an object

Element 1:

  {
     "Name":"Mr. Z",
     "Class":"Ten",
     "Roll":8,
     "Subject":{
        "Name":"Math",
        "Marks":75
     }
  },

But look at the last element Subject is an array/collection Element 3

  {
     "Name":"Mr. A",
     "Class":"Ten",
     "Roll":1,
     "Subject":[
        {
           "Name":"Math",
           "Marks":95
        },
        {
           "Name":"English",
           "Marks":75
        }
     ]
  }

JSON must be consistent Subject should be a collection or an object

if you want subject to be collection it should be defined like this

Element 3 will work with below:

public List<Subject> Subject { get; set; }

But Element 1 can work with

public Subject Subject { get; set; }

if you see carefully element 3 is collection Subject : [] where brackets shows an array/collection, whereas if you look at element 1 Subject: { } here curly brackets shows a single object that's why you have to fix your data, where ever you are returning data it should return Subject property as an Array OR as an single object.

Here is the example to understand you can play with it

sairfan
  • 970
  • 2
  • 12
  • 20
  • But using `public List Subject { get; set; }` gives new error like `Cannot deserialize the current JSON object.....Path 'Students[0].Subject'`..... – Salahuddin Ahmed Jul 26 '21 at 21:06
  • 1
    Your JSON is inconsistent, not sure where it's coming from put you have to pick one, either it's an array or it's not. An array with one element is fine, so for the first object you can have "Subject":[ { "Name":"Math", "Marks":75 } ] But you can't have it as an object for some entries and an array for others. i.e. the first error you get is because the last entry DOES have Subject defined as an array, when you fix that you then get an error because your other entries do NOT have Subject defined as an array. – bschellekens Jul 26 '21 at 21:18
  • 1
    I updated my answer, follow the example link and update those properties as shown above in the answer. I hope it will help you to understand. – sairfan Jul 26 '21 at 21:40