20

I'm using Ubuntu and dotnet 3.1, running vscode's c# extension.

I need to create a List from a JSON file, my controller will do some calculations with this model List that I will pass to it

So, here is my code and the error I'm getting.

First, I thought my error was because at model my attributes were char and C#, for what I saw, cannot interpret double-quotes for char, it should be single quotes. Before losing time removing it, I just changed my type declarations to strings and it's the same error.

Can someone help me?

ElevadorModel

using System.Collections.Generic;

namespace Bla
{
    public class ElevadorModel
    {
        public int andar { get; set; }
        public string elevador { get; set; }
        public string turno { get; set; }
    }
}

Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var path = "../input.json";

        string jsonString;
        
        ElevadorModel elevadoresModel = new ElevadorModel();

        jsonString = File.ReadAllText(path); //GetType().Name = String

        Console.WriteLine(jsonString); //WORKS           

        elevadoresModel = JsonSerializer.Deserialize<ElevadorModel>(jsonString);
    }

JSON:

enter image description here

dbc
  • 104,963
  • 20
  • 228
  • 340
nanquim
  • 1,786
  • 7
  • 32
  • 50

4 Answers4

21

Your input json has an array as the base token, whereas you're expecting an object. You need to change your deserialization to an array of objects.

var elevadoresModels = JsonSerializer.Deserialize<List<ElevadorModel>>(jsonString);
elevadoresModel = elavoresModels.First();
David L
  • 32,885
  • 8
  • 62
  • 93
  • hi, i'm new to c#. This is the correct way of initialize my list of objects now, right? List elevadoresModel = new List(); – nanquim Jan 27 '20 at 23:19
  • 2
    Correct, list instantiation is done via `new List()`. That said, in this case you do not need to initialize the list beforehand. The deserializer will create the collection for you. In my example, `var` is just compiler inference for `List`. You can use either interchangeably in this case. – David L Jan 27 '20 at 23:19
6

Your input JSON is an array of models, however you're trying to deserialize it to a single model.

var models = JsonSerializer.Deserialize<List<ElevadorModel>>(jsonString);
Evan Trimboli
  • 29,900
  • 6
  • 45
  • 66
3

This is also a problem in Blazor-Client side. For those calling a single object
e.g ClassName = await Http.GetFromJsonAsync<ClassName>($"api/ClassName/{id}");

This will fail to Deserialize. Using the same System.Text.Json it can be done by:

List<ClassName> ListName = await Http.GetFromJsonAsync<List<ClassName>>($"api/ClassName/{id}");

You can use an array or a list. For some reason System.Text.Json, does not give errors and it is successfully able Deserialize.

To access your object, knowing that it is a single object use:

ListName[0].Property

In your case the latter solution is fine but with the path as the input.

Xserge
  • 199
  • 2
  • 9
  • 2
    Isn't that essentially what the other answers stated, however, you don't clearly mention that the root cause was deserializing to a single object instead of a collection – BenCamps Jun 13 '20 at 00:53
2

In my case, I was pulling the JSON data to deserialize out of an HTTP response body. It looked like this:

var resp = await _client.GetAsync($"{endpoint}");    
var respBody = await resp.Content.ReadAsStringAsync();
var listOfInstances = JsonSerializer.Deserialize<List<modelType>>(respBody);

And the error would show up. Upon further investigation, I found the respBody string had the JSON base object (an array) wrapped in double quotes...something like this:

"[{\"prop\":\"value\"},...]"

So I added

respBody = respBody.Trim('\"');

And the error changed! Now it was pointing to an invalid character '\'. I changed that line to include

respBody = respBody.Trim('\"').Replace("\\", "");

and it began to deserialize perfectly.

For reference:

var resp = await _client.GetAsync($"{endpoint}");    
var respBody = await resp.Content.ReadAsStringAsync();
respBody = respBody.Trim('\"').Replace("\\", "");
var listOfInstances = JsonSerializer.Deserialize<List<modelType>>(respBody);
Shad
  • 400
  • 3
  • 7