1

I've got JSON data that looks like this...

{
     "generated" : "Sat, 20 Dec 3049 12:30:01",
     "1" : { ... },
     "2" : { ... },
     ...
     "2400" : { ... },
}

Personally, I would've expected an array of objects to be outputted using the JSON array syntax (this is my first foray into JSON). I'm using Json.Net to try parse this mess into an object model for querying purposes and eventually display.

I was going to use the JsonSerializationAttribute method of transforming the JSON into an object model. I've already tried going straight to XML instead but apparently this particular JSON file is not XML compatible ("1" is an invalid XML element name).

My initial object model class representing the high level snippet of JSON above is as follows:

public class MwoMapData
{
    [JsonProperty(PropertyName = "generated")]
    public DateTime Generated { get; set; }
    [JsonArray]
    public List<Planet> Planets { get; set; }
}

The resources I've read basically say that an array is not represented the way this has been and I'm totally stumped on how to parse this with Json.Net into my object model.

My question is: How do I translate the object properties into an array using Json.Net and JsonSerializationAttributes?

toadflakz
  • 7,764
  • 1
  • 27
  • 40
  • Where is an array? There is JSON object with fields, but no arrays – Sergey Berezovskiy Dec 20 '14 at 12:55
  • In Java I have worked with Jackson (http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/) in order to pass a JSON into an object. It allows you to get the JSON as you want (e.g., as a Map). – Marc Manzano Dec 20 '14 at 12:56
  • @Sergey: The "fields" are a dynamic list of items which are clearly IDs for the objects referenced. Why would someone serialise a property with the name "1", for example, especially when the array syntax exists? This is clearly a large dataset rather than an actual object with properties. – toadflakz Dec 20 '14 at 13:07
  • @Marc: Irrelevant and I'm using C# and the question is about how to deserialize those properties as an array. – toadflakz Dec 20 '14 at 13:11
  • @toadflakz _Why would someone serialise a property with the name "1", for example, especially when the array syntax exists?_ JSON has an array syntax, and your JSON is not using it. It would be rather presumptuous of your deserializer to assume it was an array just because it had numeric property names (especially when it has a non-numeric property name). – JLRishe Dec 20 '14 at 14:28
  • @JLRishe: No, it would be correcting bad data schema design, which is what this clearly is, but I'm not surprised considering the other outputs of this particular organisation. There is no way I'm creating a C# class with 2400 properties. – toadflakz Dec 20 '14 at 14:38
  • @toadflakz Again, it's not the deserializer's job to assume something is an array when it's not, or to auto-correct someone's bad schema design without being asked to do so. The deserializer works with the data it's given, and there may be settings to change its behavior, but in my opinion, the default behavior should not be to make any more assumptions about the input than it has to. – JLRishe Dec 20 '14 at 14:48
  • @JLRishe: Under normal circumstances, I would agree with you. However, considering that using a serialization attribute automatically implies tight coupling between data model and serializer, in this case it would then be the deserializer's job to ensure that the data is coherent for the data model specified. Normally I'm against this technology because of the coupling, but CBA as it's a private project I need to prototype quickly. If I show you the full data you might understand the assumption: https://static.mwomercs.com/data/cw/mapdata.json – toadflakz Dec 20 '14 at 14:59

2 Answers2

2

If you are using Json.NET you can implement custom Deserialzer by creating a class that inherits from abstract class JsonConverter. You can then override method called ReadJson:

class CustomJson : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            //if you only deserialize, you will probably not need this
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var output = new object(); //instance of your class
            do
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    int number;
                    if (int.TryParse(reader.Value.ToString(), out number))
                    {
                        //detecting the number
                    }
                    else
                    {
                        //not a number
                    }
                }
                else
                {
                    //read other stuff
                }    
            } while (reader.Read());

            return output;
        }

        public override bool CanConvert(Type objectType)
        {
            //detect your type
        }
    }

And then use it:

var deserialized = JsonConvert.DeserializeObject<YourClass>(json, new CustomJson());

For other hints how to implement JsonConverter class see this posts:

Community
  • 1
  • 1
Marcin Zablocki
  • 10,171
  • 1
  • 37
  • 47
  • Thanks - I was hoping it was default functionality, but oh well! – toadflakz Dec 20 '14 at 13:27
  • 1
    Json.NET deserializes objects as they are represented in JSON string. Only if input JSON have different syntax (like in your example) and you want to parse properties in a different way - then you implement JsonConverter class. – Marcin Zablocki Dec 20 '14 at 13:30
0

You deserialise it using this code

Dictionary<string,Yourclass> data = JsonConvert.DeserializeObject<Dictionary<string,Yourclass>>(jsonString);

You can then iterate through your dictionary

Tien Dinh
  • 1,037
  • 7
  • 12