0

I am attempting to deserialize a piece of JSON with a specific structure like so:

{  
    "label1": "value1",  
    "label2": [  
        [  
            [  
                "concept_id_1",  
                "concept_1"  
            ],  
            score_1  
        ],  
        [  
            [  
                "concept_id_2",  
                "concept_2"  
            ],  
            score_2  
        ],  
        ……  
    ],  
    "label3": "value3",  
    "label4": "value4"  
}  

For what it's worth, the scores are floats and everything else is a string. The number of returned concepts under "label2" is variable.

I'm attempting to deserialize it using JSON.net. The only content I actually care about is the inside nest of arrays labelled "label2", however the lack of labels inside the arrays is blocking me at every turn.

I've tried a variety of approaches, but the most successful so far seems to be this:

public class Parsed_JSON {
    public string label1 { get; set; }
    public ICollection<Full_Result> label2 { get; set; }
    public string label3 { get; set; }
    public string label4 { get; set; }
}

public class Full_Result {
    public IList<string> values { get; set; }
    public float score { get; set; }
}

Parsed_JSON result = JsonConvert.DeserializeObject<Parsed_JSON>(JSON);

However this is failing with the error:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'JSON_Parsing+Full_Result' 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.

Ultimately I'll be looking to iterate through the contents of label2 so that I can build a DataTable of them like so:

concept_id_1   concept_1   score_1  
concept_id_2   concept_2   score_2

How can I deserialize this JSON?

8
  • stackoverflow.com/a/48023576/4180382 Commented Oct 10, 2018 at 15:35
  • This: [ "concept_id_1", "concept_1" ], score_1 is not the class Full_Result that you have described, it is an array of different types Commented Oct 10, 2018 at 15:37
  • @MarkiianBenovskyi Thank you, are you able to suggest how I can modify the Parsed_JSON class appropriately? Commented Oct 10, 2018 at 15:41
  • @OleEHDufour Thank you, that looks really useful, but unfortunately I'm not able to use Visual Studio (long story) Commented Oct 10, 2018 at 15:42
  • 1
    I can suggest you to use dynamic objects for that stackoverflow.com/a/9326146/4697963 Commented Oct 10, 2018 at 15:43

1 Answer 1

1

You can use the custom JsonConverter ObjectToArrayConverter<Full_Result> from this answer to C# JSON.NET - Deserialize response that uses an unusual data structure to deserialize your JSON into your existing typed data model. Modify Full_Result as follows:

[JsonConverter(typeof(ObjectToArrayConverter<Full_Result>))]
public class Full_Result 
{
    [JsonProperty(Order = 1)]
    public IList<string> values { get; set; }
    [JsonProperty(Order = 2)]
    public float score { get; set; }
}

And you will now be able to deserialize as follows:

Parsed_JSON result = JsonConvert.DeserializeObject<Parsed_JSON>(JSON);

Notes:

  • ObjectToArrayConverter<T> works by mapping the serializable members of T to an array, where the array sequence is defined by the value of the JsonPropertyAttribute.Order attribute applied to each member. Data contract attributes with DataMemberAttribute.Order set could be used instead, if you prefer.

  • In your JSON the "score" values are not actually numbers:

    score_1
    score_2
    

    I am assuming that this is a typo in the question and that these values are in fact well-formed numbers as defined by the JSON standard.

Sample fiddle here.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, this is perfect for me!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.