Reputation: 83
I am trying to read some data from the Eurostat server. I deserialize the string returned by the server using the Newtonsoft library:
Product product = JsonConvert.DeserializeObject<Product>(responseText);
The full JSON string is:
{
"version": "2.0",
"label": "Production from aquaculture excluding hatcheries and nurseries (from 2008 onwards)",
"href": "http://ec.europa.eu/eurostat/wdds/rest/data/v2.1/json/en/fish_aq2a?precision=1&species=SAL&aquaenv=SEA&fishreg=0&fishreg=10&fishreg=27&fishreg=5&fishreg=9&fishreg=37&fishreg=34&fishreg=NSP&fishreg=4&fishreg=1&unit=EUR&unit=EUR_T&unit=TLW&aquameth=CAG",
"source": "Eurostat",
"updated": "2017-10-10",
"status": {
"0": ":",
"3": ":",
"5": ":",
"6": ":",
"7": ":",
"13": ":",
"14": ":",
"15": ":",
"17": ":",
"18": ":",
"19": ":",
"20": ":",
"21": ":",
"22": ":",
"23": ":",
"24": ":",
"27": ":",
"28": ":",
"29": ":",
"30": ":",
"31": ":",
"37": ":",
"38": ":",
"39": ":",
"40": ":",
"45": ":",
"46": ":",
"47": ":",
"48": ":",
"51": ":",
"53": ":",
"54": ":",
"55": ":",
"61": ":",
"62": ":",
"63": ":",
"65": ":",
"66": ":",
"67": ":",
"68": ":",
"69": ":",
"70": ":",
"71": ":",
"72": ":",
"75": ":",
"76": ":",
"77": ":",
"78": ":",
"79": ":",
"85": ":",
"86": ":",
"87": ":",
"88": ":",
"93": ":",
"94": ":",
"95": ":",
"96": ":",
"99": ":",
"101": ":",
"102": ":",
"103": ":",
"109": ":",
"110": ":",
"111": ":",
"113": ":",
"114": ":",
"115": ":",
"116": ":",
"117": ":",
"118": ":",
"119": ":",
"120": ":",
"123": ":",
"124": ":",
"125": ":",
"126": ":",
"127": ":",
"133": ":",
"134": ":",
"135": ":",
"136": ":",
"141": ":",
"142": ":",
"143": ":",
"144": ":",
"147": ":",
"149": ":",
"150": ":",
"151": ":",
"157": ":",
"158": ":",
"159": ":",
"161": ":",
"162": ":",
"163": ":",
"164": ":",
"165": ":",
"166": ":",
"167": ":",
"168": ":",
"171": ":",
"172": ":",
"173": ":",
"174": ":",
"175": ":",
"181": ":",
"182": ":",
"183": ":",
"184": ":",
"189": ":",
"190": ":",
"191": ":",
"192": ":",
"195": ":",
"197": ":",
"198": ":",
"199": ":",
"205": ":",
"206": ":",
"207": ":",
"209": ":",
"210": ":",
"211": ":",
"212": ":",
"213": ":",
"214": ":",
"215": ":",
"216": ":",
"219": ":",
"220": ":",
"221": ":",
"222": ":",
"223": ":",
"229": ":",
"230": ":",
"231": ":",
"232": ":",
"237": ":",
"238": ":",
"239": ":",
"240": ":",
"243": ":",
"245": ":",
"246": ":",
"247": ":",
"253": ":",
"254": ":",
"255": ":",
"257": ":",
"258": ":",
"259": ":",
"260": ":",
"261": ":",
"262": ":",
"263": ":",
"264": ":",
"267": ":",
"268": ":",
"269": ":",
"270": ":",
"271": ":",
"277": ":",
"278": ":",
"279": ":",
"280": ":",
"285": ":",
"286": ":",
"287": ":",
"288": ":",
"291": ":",
"293": ":",
"294": ":",
"295": ":",
"301": ":",
"302": ":",
"303": ":",
"305": ":",
"306": ":",
"307": ":",
"308": ":",
"309": ":",
"310": ":",
"311": ":",
"312": ":",
"315": ":",
"316": ":",
"317": ":",
"318": ":",
"319": ":",
"325": ":",
"326": ":",
"327": ":",
"328": ":",
"333": ":",
"334": ":",
"335": ":",
"336": ":",
"339": ":",
"341": ":",
"342": ":",
"343": ":",
"349": ":",
"350": ":",
"351": ":",
"353": ":",
"354": ":",
"355": ":",
"356": ":",
"357": ":",
"358": ":",
"359": ":",
"360": ":",
"363": ":",
"364": ":",
"365": ":",
"366": ":",
"367": ":",
"373": ":",
"374": ":",
"375": ":",
"376": ":",
"381": ":",
"382": ":",
"383": ":",
"384": ":",
"387": ":",
"389": ":",
"390": ":",
"391": ":",
"397": ":",
"398": ":",
"399": ":",
"401": ":",
"402": ":",
"403": ":",
"404": ":",
"405": ":",
"406": ":",
"407": ":",
"408": ":",
"411": ":",
"412": ":",
"413": ":",
"414": ":",
"415": ":",
"421": ":",
"422": ":",
"423": ":",
"424": ":",
"429": ":",
"430": ":",
"431": ":"
},
"extension": {
"datasetId": "fish_aq2a",
"lang": "EN",
"description": null,
"subTitle": null,
"status": {
"label": {
":": "not available"
}
}
},
"class": "dataset",
"value": {
"1": 3243,
"2": 356479,
"4": 14938,
"8": 6007500,
"9": 529723936.38,
"10": 585804684.37,
"11": 677939444.53,
"12": 641218586.15,
"16": 6007500,
"25": 65367944,
"26": 70585535,
"32": 1851387298,
"33": 2311910972,
"34": 3562084862,
"35": 3454753657,
"36": 3739702550,
"41": 464352749,
"42": 514862671,
"43": 677939445,
"44": 641179927,
"49": 1989,
"50": 4501,
"52": 3734,
"56": 4500,
"57": 3376.93,
"58": 3441.86,
"59": 4286.31,
"60": 3946.37,
"64": 4500,
"73": 5354,
"74": 4499,
"80": 2510,
"81": 2679,
"82": 3791,
"83": 3241,
"84": 3035,
"89": 3210,
"90": 3334,
"91": 4286,
"92": 3946,
"97": 2,
"98": 79,
"100": 4,
"104": 1335,
"105": 156865.63,
"106": 170200,
"107": 158164,
"108": 162483,
"112": 1335,
"121": 12210,
"122": 15691,
"128": 737694,
"129": 862908,
"130": 939575,
"131": 1065975,
"132": 1232095,
"137": 144654,
"138": 154430,
"139": 158164,
"140": 162479,
"145": 3243,
"146": 356479,
"148": 14938,
"152": 6007500,
"153": 529723936.38,
"154": 585804684.37,
"155": 677939444.53,
"156": 641218586.15,
"160": 6007500,
"169": 65367944,
"170": 70585535,
"176": 1851387298,
"177": 2311910972,
"178": 3562084862,
"179": 3454753657,
"180": 3739702550,
"185": 464352749,
"186": 514862671,
"187": 677939445,
"188": 641179927,
"193": 1989,
"194": 4501,
"196": 3734,
"200": 4500,
"201": 3376.93,
"202": 3441.86,
"203": 4286.31,
"204": 3946.37,
"208": 4500,
"217": 5354,
"218": 4499,
"224": 2510,
"225": 2679,
"226": 3791,
"227": 3241,
"228": 3035,
"233": 3210,
"234": 3334,
"235": 4286,
"236": 3946,
"241": 2,
"242": 79,
"244": 4,
"248": 1335,
"249": 156865.63,
"250": 170200,
"251": 158164,
"252": 162483,
"256": 1335,
"265": 12210,
"266": 15691,
"272": 737694,
"273": 862908,
"274": 939575,
"275": 1065975,
"276": 1232095,
"281": 144654,
"282": 154430,
"283": 158164,
"284": 162479,
"289": 3243,
"290": 356479,
"292": 14938,
"296": 6007500,
"297": 529723936.38,
"298": 585804684.37,
"299": 677939444.53,
"300": 641218586.15,
"304": 6007500,
"313": 65367944,
"314": 70585535,
"320": 1851387298,
"321": 2311910972,
"322": 3562084862,
"323": 3454753657,
"324": 3739702550,
"329": 464352749,
"330": 514862671,
"331": 677939445,
"332": 641179927,
"337": 1989,
"338": 4501,
"340": 3734,
"344": 4500,
"345": 3376.93,
"346": 3441.86,
"347": 4286.31,
"348": 3946.37,
"352": 4500,
"361": 5354,
"362": 4499,
"368": 2510,
"369": 2679,
"370": 3791,
"371": 3241,
"372": 3035,
"377": 3210,
"378": 3334,
"379": 4286,
"380": 3946,
"385": 2,
"386": 79,
"388": 4,
"392": 1335,
"393": 156865.63,
"394": 170200,
"395": 158164,
"396": 162483,
"400": 1335,
"409": 12210,
"410": 15691,
"416": 737694,
"417": 862908,
"418": 939575,
"419": 1065975,
"420": 1232095,
"425": 144654,
"426": 154430,
"427": 158164,
"428": 162479
},
"dimension": {
"aquameth": {
"label": "aquameth",
"category": {
"index": {
"CAG": 0
},
"label": {
"CAG": "Cages"
}
}
},
"aquaenv": {
"label": "aquaenv",
"category": {
"index": {
"SEA": 0
},
"label": {
"SEA": "Seawater"
}
}
},
"species": {
"label": "species",
"category": {
"index": {
"SAL": 0
},
"label": {
"SAL": "Atlantic salmon - Salmo salar"
}
}
},
"fishreg": {
"label": "fishreg",
"category": {
"index": {
"0": 0,
"10": 1,
"27": 2
},
"label": {
"0": "Total fishing areas",
"10": "Marine areas",
"27": "Atlantic, Northeast"
}
}
},
"unit": {
"label": "unit",
"category": {
"index": {
"EUR": 0,
"EUR_T": 1,
"TLW": 2
},
"label": {
"EUR": "Euro",
"EUR_T": "Euro per tonne",
"TLW": "Tonnes live weight"
}
}
},
"geo": {
"label": "geo",
"category": {
"index": {
"ES": 0,
"EU28": 1,
"FR": 2,
"IE": 3,
"NO": 4,
"UK": 5
},
"label": {
"ES": "Spain",
"EU28": "European Union (28 countries)",
"FR": "France",
"IE": "Ireland",
"NO": "Norway",
"UK": "United Kingdom"
}
}
},
"time": {
"label": "time",
"category": {
"index": {
"2008": 0,
"2009": 1,
"2010": 2,
"2011": 3,
"2012": 4,
"2013": 5,
"2014": 6,
"2015": 7
},
"label": {
"2008": "2008",
"2009": "2009",
"2010": "2010",
"2011": "2011",
"2012": "2012",
"2013": "2013",
"2014": "2014",
"2015": "2015"
}
}
}
},
"id": [
"aquameth",
"aquaenv",
"species",
"fishreg",
"unit",
"geo",
"time"
],
"size": [
1,
1,
1,
3,
3,
6,
8
]
}
In my Product class (MSVS 2015 C#) I have:
public Dictionary<string, dynamic> Extension { get; set; }
which works fine until I get to the "status" key, which gives an error.
The way I am getting around that is:
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.Extension) + ":";
foreach (string key in product.Extension.Keys)
{
MyRow++;
MyCol = 0;
dynamic myvalue = key;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue;
if (key == "status")
break;
MyCol = 1;
myvalue = product.Extension[key];
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue;
}
Note: the MyRow & MyCol variables are for output to a spreadsheet add-in, and not relevant to the issue. I've checked a number of examples on the web, mainly on stackoverflow, but cannot manage to resolve.
Upvotes: 0
Views: 80
Reputation: 83
The way to read the json "dimension" component into a C# class is to create the following:
public class Dimension
{
public DimensionAquameth aquameth { get; set; }
}
public class DimensionAquameth
{
public string label { get; set; }
public DimensionCategory category { get; set; }
}
public class DimensionCategory
{
public Dictionary<string, string> index { get; set; }
public Dictionary<string, string> label { get; set; }
}
and then add:
public Dimension dimension { get; set; }
to the Product class.
And in the code that parses the deserialized json:
// Dimension field
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension) + ":";
// aquameth
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension.aquameth) + ":";
// label
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension.aquameth.label) + ":";
MyCol = 1;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = product.dimension.aquameth.label;
// category
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension.aquameth.category) + ":";
// category index
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension.aquameth.category.index) + ":";
// CAG
foreach (string key in product.dimension.aquameth.category.index.Keys)
{
MyRow++;
MyCol = 0;
dynamic myvalue = key;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue + ":";
MyCol = 1;
myvalue = product.dimension.aquameth.category.index[key];
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue;
}
MyRow++;
MyCol = 0;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = nameof(product.dimension.aquameth.category.label) + ":";
// CAG
foreach (string key in product.dimension.aquameth.category.label.Keys)
{
MyRow++;
MyCol = 0;
dynamic myvalue = key;
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue + ":";
MyCol = 1;
myvalue = product.dimension.aquameth.category.label[key];
QueryOutputWS.ActiveWorksheet.Cells[MyRow, MyCol].Value = myvalue;
}
Please note that the QueryOutputWS reference, as well as MyRow, MyCol are specific to outputting the results decoded fields to a SpreadsheetGear worksheet - you can use any other output approach, including console outputs etc.
Upvotes: 1
Reputation: 247153
Because of the ":"
JSON key it will cause some problems with using dynamic
and duck typing.
Consider creating a strong-type for that property Like below
public class Extension {
public string datasetId { get; set; }
public string lang { get; set; }
public string description { get; set; }
public string subTitle { get; set; }
public ExtensionStatus status { get; set; }
}
public class ExtensionStatus {
public Dictionary<string, string> label { get; set; }
}
and have
public Extension extension { get; set; }
in your Product
class
For dimension
property, what you need to do is look for the common pattern among the nested objects.
Based on provided JSON Dimension
would resolve to the following
public class Dimension {
public DimensionDetail aquameth { get; set; }
public DimensionDetail aquaenv { get; set; }
public DimensionDetail species { get; set; }
public DimensionDetail fishreg { get; set; }
public DimensionDetail unit { get; set; }
public DimensionDetail geo { get; set; }
public DimensionDetail time { get; set; }
}
public class DimensionDetail {
public string label { get; set; }
public Category category { get; set; }
}
public class Category {
public Dictionary<string, int> index { get; set; }
public Dictionary<string, string> label { get; set; }
}
With the property set on Product
as
public Dimension dimension { get; set; }
That way after deserializing the string you can access it like
var product = JsonConvert.DeserializeObject<Product>(responseText);
var value = product.extension.status.label[":"]; //value should equal "not available"
Upvotes: 1