kanpeki
kanpeki

Reputation: 445

Trouble deserializing JSON (got value array when single value expected)

I am reading data from a graph database and getting the response as a dynamic object. I go through the results and try to deserialize them as so:

var e = results.GetEnumerator();

while (e.MoveNext())
{
    var serialized = JsonConvert.SerializeObject(e.Current);
    // {"FlagCalculateclientside":[false],"Description":["Some detailed info"], "Name": ["MyDetailedEntity"]}
    var val = JsonConvert.DeserializeObject<MyObject>(serialized);
}

public class MyObject
{
    public bool FlagCalculateclientside { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
}

But I get the following error:

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: [. Path 'FlagCalculateclientside', line 1, position 28. at Newtonsoft.Json.JsonTextReader.ReadAsBoolean() at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter) ...

I guess this is because the values are in arrays, but only a single value per key was expected.

Any idea how to fix this?

Upvotes: 0

Views: 752

Answers (1)

DavidG
DavidG

Reputation: 119016

Your model doesn't match your JSON, all of the properties are arrays, in other words they are surround with [...]. To fix, change the model to this:

public class MyObject
{
    public List<bool> FlagCalculateclientside { get; set; }
    public List<string> Description { get; set; }
    public List<string> Name { get; set; }
}

An alternative would be to use a custom converter, for example:

public class ArrayConverter<T> : JsonConverter<T>
{
    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);

        //This isn't the best code but shows you what you need to do.
        return token.ToObject<List<T>>().First();
    }

    public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

And change your model to this:

public class MyObject
{
    [JsonConverter(typeof(ArrayConverter<bool>))]
    public bool FlagCalculateclientside { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Description { get; set; }

    [JsonConverter(typeof(ArrayConverter<string>))]
    public string Name { get; set; }
}

Upvotes: 1

Related Questions