3

I'm trying to deserialize a Json string that has an array with no containing brackets.

{ "id": "983f90j30909j3f",
  "moreInfo": {
      "info193802": { ... },
      "info920938": { ... },
      "info849028": { ... }
  }
}

This "moreInfo" is an array of items with dynamic keys and does not have square brackets telling that it's an array.

I've tried to deserialize it with Newtonsoft.Json normally ( JsonConvert.DeserializeObject<rootObject>() ) but since this json array isn't really an array it throws an error. Here is my class:

public class RootObject
{
    public string Id { get; set; }
    public MoreInfo MoreInfo { get; set; }
}


public class MoreInfo
{   
    public List<Info> InfoList{ get; set; }
}

public class Info
{
    properties...
}

How do I go about deserializing this?

2
  • use IDictionary<string, Info> MoreInfo { get; set; } for the multiple keys. Commented Dec 14, 2017 at 0:27
  • 3
    You're misunderstanding something important: moreInfo is not an array. It is an object, just like the root object. Thinking it is an array is where you're getting in trouble. Because it's an object and not an array, you need to represent it as a dictionary instead of a list, as explained in some of the answers. Commented Dec 14, 2017 at 0:34

2 Answers 2

2

Update the root object to use IDictionary<string, Info>

public class RootObject {
    public string Id { get; set; }
    public IDictionary<string, Info> MoreInfo { get; set; }
}

the dynamic keys will be the key in the dictionary.

Once parsed you access the info via the dictionary's keys

Info info = rootObject.MoreInfo["info193802"];
Sign up to request clarification or add additional context in comments.

1 Comment

Clever approach, completely overlooked that solution.
1

Newtonsoft can correctly parse the data. The data represents objects, they happen to be nested fairly deep. You can accomplish it a couple of ways, for instance:

dynamic json = JsonConvert.DeserializeObject(response);
var info = json["moreinfo:info913802:example"].Value;

Your other option would be to use Visual Studio, let it create an object you can deserialize to.

  1. Edit
  2. Paste Special
  3. As JSON

Output would be:

public class Rootobject
{
    public string id { get; set; }
    public Moreinfo moreInfo { get; set; }
}

public class Moreinfo
{
    public Info193802 info193802 { get; set; }
    public Info920938 info920938 { get; set; }
    public Info849028 info849028 { get; set; }
}

public class Info193802
{
    public string Example { get; set; }
}

public class Info920938
{
    public string Example { get; set; }
}

public class Info849028
{
    public string Example { get; set; }
}

The source JSON I used was yours, with one exception:

{ "id": "983f90j30909j3f",
  "moreInfo": {
      "info193802": { "Example" : "Blah" },
      "info920938": { "Example" : "Blah" },
      "info849028": {"Example" : "Blah" }
  }
}

4 Comments

That generated code would work for the exact JSON that is listed in the question, but doesn't it stand to reason that it was just an example, and a real dataset may not use those three specific infoNNNNNN property names but may have any other similar names, and more or fewer of them? I don't think hard coding classes with these property names will work in the long run.
@MichaelGeary That is possible, but why would the JSON be returned so irregular and inconsistent? If you're consuming an API it should be consistent, I think the OP needs to provide more information.
The 'info93739' keys are just placeholders, but they do change everytime, and have varying numbers of them in each 'moreInfo'
Those infoNNNNNN keys look very regular and consistent to me, and I could imagine a structure just like this in any number of scenarios. Examples would be the list of related questions on the right of this SO page, or an FAQ that has many entries with links at the bottom of each entry to other related topics. In both those cases you would expect random-looking numbers like this, but a different set of numbers for each query.

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.