0

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?

5
  • In question commented code is your json response? Commented May 30, 2019 at 10:57
  • Where does results come from? How is that data/object setup? Commented May 30, 2019 at 10:58
  • @A.M. Patel Yes, it's the value of 'serialized' Commented May 30, 2019 at 10:58
  • @Tony Abrams I make a request to the Gremlin client, like so: var results = await gremlinClient.SubmitAsync<dynamic>(requestScript).ConfigureAwait(false); requestScript just holds my Gremlin query string Commented May 30, 2019 at 11:01
  • What does the Gremlin query look like? Commented May 30, 2019 at 11:04

1 Answer 1

1

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; }
}
Sign up to request clarification or add additional context in comments.

6 Comments

While this does 'fix' the issue, it doesn't make sense to make the model have arrays - as the OP states that they only expect one value per field in the model.
@TonyAbrams OP asked how to fix the issue and this does it. The alternative is to fix the Gremlin query, but that's pretty complicated to do. Generally Gremlin gives you property values as arrays.
Thank you for the answer. What I am hoping to be able to do is map the first property in each array to the property in my model. Those arrays will never have more than one element in them, it's just that the response is like that...
@kanpeki Well that means you need to change your query which is a completely different question.
@DavidG I'm not very familiar with this, but is there no way to make a custom deserializer?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.