-5
{
"00AK": {
        "icao": "00AK",
        "iata": "",
        "name": "Lowell Field",
        "city": "Anchor Point",
        "state": "Alaska",
        "country": "US",
        "elevation": 450,
        "lat": 59.94919968,
        "lon": -151.695999146,
        "tz": "America\/Anchorage"
    },
    "00AL": {
        "icao": "00AL",
        "iata": "",
        "name": "Epps Airpark",
        "city": "Harvest",
        "state": "Alabama",
        "country": "US",
        "elevation": 820,
        "lat": 34.8647994995,
        "lon": -86.7703018188,
        "tz": "America\/Chicago"
    }
}

Would like to work with json which contains list of airports available in all over world.When we are creating classes for above json, it will create classes for each airport.

So if it is 100k airports, 100k classes are generated with similar property. Is there anyway to simplify this? Can we use any generics?

James Z
  • 12,209
  • 10
  • 24
  • 44
  • 2
    one class for each airport... but - ***why***? how do the airport-objects differ _except for the data they contain_? what _functional_ difference do they need to have? whatever problem you're trying to solve by this, i bet there's at least a dozen better ways to solve it. (but if you insist on solving it that way, that question has already been [asked](https://stackoverflow.com/questions/11099466/using-a-custom-type-discriminator-to-tell-json-net-which-type-of-a-class-hierarc)) – Franz Gleichmann Oct 30 '20 at 06:52
  • 3
    This question gets asked on a daily basis and we still have no canonical? Create a class for one airport, and deseralize into a `Dictionary`. – CodeCaster Oct 30 '20 at 06:56
  • @Franz they mean if you paste this in Json2CSharp or Edit/Paste Special/Paste JSON as Classes in Visual Studio, it will generate a class for each key, and that's exactly what they don't want. – CodeCaster Oct 30 '20 at 06:58
  • https://app.quicktype.io?share=MacRIw43hNtvfdH3A94l – mjwills Oct 30 '20 at 07:51

2 Answers2

2

I'd just make a single class for the airport then Deserialize to a Dictionary<string,Airport>

Here is a simpler example:

    var json =  @"{ ""00AL"": {""elevation"":450}, ""00AK"":{""elevation"":820} }";
    var obj = JsonConvert.DeserializeObject<Dictionary<string,Airport>>(json);
         
    foreach(var item in obj) {
      Console.WriteLine($"{item.Key}={item.Value.Elevation}");
    }
        



public class Airport
{
    [JsonProperty("elevation")]
    public int Elevation { get; set; } 
}

You've got one airport class, and you can enumerate the Values of the resulting dictionary. If the json adds more airports, your dictionary gets more values but you still have only one airport class

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
-1

Actually, this is not that hard when you use the JsonProperty attribute

public class Class1    {
        [JsonProperty("icao")]
        public string Icao { get; set; } 

        [JsonProperty("iata")]
        public string Iata { get; set; } 

        [JsonProperty("name")]
        public string Name { get; set; } 

        [JsonProperty("city")]
        public string City { get; set; } 

        [JsonProperty("state")]
        public string State { get; set; } 

        [JsonProperty("country")]
        public string Country { get; set; } 

        [JsonProperty("elevation")]
        public int Elevation { get; set; } 

        [JsonProperty("lat")]
        public double Latitude { get; set; } 

        [JsonProperty("lon")]
        public double Longtitude { get; set; } 

        [JsonProperty("tz")]
        public string Tz { get; set; } 
    }

    

    public class Root    {
        [JsonProperty("00AK")]
        public Class1 GeoDatAK{ get; set; } 

        [JsonProperty("00AL")]
        public Class1 GeoDatAL { get; set; } 
    }

to instantiate it do:

Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 

I personally use the properties to shorten the Json send between services and mobile applications. this becomes especially important when using obfuscation as obfuscated classes that are not public should get renamed.

Look at [JsonConstructor] annotation for internal constructors and use parameters named with the properties

in your class this would be:

[JsonConstructor]
internal Class1(string icao)
{
    this.Icao=icao;
}
Walter Verhoeven
  • 3,867
  • 27
  • 36
  • this is exactly what the OP does NOT want. Why different classes Class1 and 2 which are identical. And the point you missed is also that this JSON was just a short example for something that in reality might be thousands of objects (i.e. airports of the world) – jps Oct 30 '20 at 07:05
  • @jsp feel free to use the same class on both properties, no stress, no limitations – Walter Verhoeven Oct 30 '20 at 07:23
  • 1
    *use the same class on both properties* - did you understand that we talk about thousands of properties in reality then? Technically it might be working what you propose (though I'm not sure about the limitations of the number of properties per class) but practically, as mentioned above, this solution is not feasable, because the real JSON contains maybe > 100.000 (the indian english word lakh) objects. – jps Oct 30 '20 at 07:30
  • Thank you so much, i will try and let you know..... – VIGNESH WARAN Oct 30 '20 at 07:48