Why is my inner array not being deserialized? - c#

I have some JSON which I'd like to deserialize into Objects.
I'm trying to do it like this, but I only get some of the JSON deserialized and the vin and vout JSON are either 0s or nulls. What am I doing wrong?
Transaction t = JsonConvert.DeserializeObject<RPCResponse<Transaction>>(json).result;
JSON:
{
"result": {
"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000",
"txid": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
"hash": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
"size": 134,
"version": 1,
"locktime": 0,
"vin": [
{
"coinbase": "04ffff001d0104",
"sequence": 4294967295
}
],
"vout": [
{
"value": 50.00000000,
"n": 0,
"scriptPubKey": {
"asm": "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee OP_CHECKSIG",
"hex": "410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac",
"reqSigs": 1,
"type": "pubkey",
"addresses": [
"12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX"
]
}
}
],
"blockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048",
"confirmations": 563356,
"time": 1231469665,
"blocktime": 1231469665
},
"error": null,
"id": "getrawtransaction"
}
The output in the debugger looks like this:
My Classes look like this:
public class RPCResponse<T>
{
public T result { get; set; }
public string error { get; set; }
public string id { get; set; }
}
public class Transaction
{
public string TxId { get; set; }
public long Size { get; set; }
public long Version { get; set; }
public long LockTime { get; set; }
public TransactionInputCoinbase[] Vin { get; set; }
public TransactionOutput[] Vout { get; set; }
public string BlockHash { get; set; }
public long Time { get; set; }
}
public class TransactionInputCoinbase
{
string Coinbase { get; set; }
string Sequence { get; set; }
}
public class TransactionOutput
{
decimal Value { get; set; }
int N { get; set; }
ScriptPubKey ScriptPubKey { get; set; }
}
public class ScriptPubKey
{
string Asm { get; set; }
string Hex { get; set; }
long ReqSigs { get; set; }
string Type { get; set; }
string[] Addresses { get; set; }
}

The lack of public properties on the said objects
For example
public class TransactionInputCoinbase
{
string Coinbase { get; set; } //<--NOT PUBLIC
string Sequence { get; set; } //<--NOT PUBLIC
}
means those properties will never be set when initialized via deserialization.
The same goes for TransactionOutput and ScriptPubKey based on the code originally provided.

Related

How to deserialize specific json string to ASP.NET MVC model?

I have json string like this:
{
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
...
"quote": {
"USD": {
"price": 9283.92,
"volume_24h": 7155680000,
"percent_change_1h": -0.152774,
"percent_change_24h": 0.518894,
"market_cap": 158055024432,
"last_updated": "2018-08-09T22:53:32.000Z"
},
"BTC": {
"price": 1,
"volume_24h": 772012,
"percent_change_1h": 0,
"percent_change_24h": 0,
"percent_change_7d": 0,
"market_cap": 17024600,
"last_updated": "2018-08-09T22:53:32.000Z"
}
}
},
// objects like previous from which i need the data
],
"status": {
"timestamp": "2018-06-02T22:51:28.209Z",
...
}
}
How do I deserialize it into models like this:
public class MyModel
{
public string Name { get; set; }
public string Symbol { get; set; }
public string Price { get; set; }
public double Percent_change_1h { get; set; }
public double Percent_change_24h { get; set; }
public long Market_cap { get; set; }
public DateTime Last_updated { get; set; }
}
The field names in the model are the same as the key names in json string.
I'm new to C# and I couldn't find any helpful information about my question, especially because of this specific json string structure.
I'll be glad if you direct me any good links about this.
The model seems to be something like this.
public class Model
{
public List<Datum> data { get; set; }
public Status status { get; set; }
}
public class Status
{
public DateTime timestamp { get; set; }
}
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public Quote quote { get; set; }
}
public class Quote
{
public USD USD { get; set; }
public BTC BTC { get; set; }
}
public class BTC
{
public int price { get; set; }
public int volume_24h { get; set; }
public int percent_change_1h { get; set; }
public int percent_change_24h { get; set; }
public int percent_change_7d { get; set; }
public int market_cap { get; set; }
public DateTime last_updated { get; set; }
}
public class USD
{
public double price { get; set; }
public object volume_24h { get; set; }
public double percent_change_1h { get; set; }
public double percent_change_24h { get; set; }
public object market_cap { get; set; }
public DateTime last_updated { get; set; }
}
You can also try creating model on (http://json2csharp.com/) by copying your valid json string.
Please let me know if this helps
Bottom line: You can (manually), but that's probably not what you're looking for.
Reason: Your model doesn't match the JSON structure, hence "manual"
You can use readily available tools in either Visual Studio or VS Code to help you with creating the proper model (e.g. Paste JSON As Code)
Once you get the "proper" model/s ready, go over JSON documentation for (de)serializing.
I had to fix some syntax errors on your json, so fixed version is following:
{
"data": [
{
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"quote": {
"USD": {
"price": 9283.92,
"volume_24h": 7155680000,
"percent_change_1h": -0.152774,
"percent_change_24h": 0.518894,
"market_cap": 158055024432,
"last_updated": "2018-08-09T22:53:32.000Z"
},
"BTC": {
"price": 1,
"volume_24h": 772012,
"percent_change_1h": 0,
"percent_change_24h": 0,
"percent_change_7d": 0,
"market_cap": 17024600,
"last_updated": "2018-08-09T22:53:32.000Z"
}
}
}
],
"status": {
"timestamp": "2018-06-02T22:51:28.209Z"
}
}
Here is C# model classes matching with previous json:
public class Rootobject
{
public Datum[] data { get; set; }
public Status status { get; set; }
}
public class Status
{
public DateTime timestamp { get; set; }
}
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public Quote quote { get; set; }
}
public class Quote
{
public USD USD { get; set; }
public BTC BTC { get; set; }
}
public class USD
{
public float price { get; set; }
public long volume_24h { get; set; }
public float percent_change_1h { get; set; }
public float percent_change_24h { get; set; }
public long market_cap { get; set; }
public DateTime last_updated { get; set; }
}
public class BTC
{
public int price { get; set; }
public int volume_24h { get; set; }
public int percent_change_1h { get; set; }
public int percent_change_24h { get; set; }
public int percent_change_7d { get; set; }
public int market_cap { get; set; }
public DateTime last_updated { get; set; }
}
Here is code snippet which you can use when deserializing your json. This snippet uses Json.NET-library.
var obj = JsonConvert.DeserializeObject<Rootobject>(File.ReadAllText("object.json"));

Deserializing result of steam storefront api using RestSharp always returns null

I've been trying to use the steam storefront api http://store.steampowered.com/api/.
The problem is that when I feed the result of the api to RestSharp, the data is always null.
So my question is how do I get the Rest call deserialized?
First, this is what you would be expecting when calling appdetails?appids=[appid]
{
"3400": {
"success": true,
"data": {
"type": "game",
"name": "Hammer Heads Deluxe",
"steam_appid": 3400,
"required_age": 0,
"is_free": false,
"detailed_description": "",
"about_the_game": "",
"short_description": "",
"supported_languages": "English",
"header_image": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/header.jpg?t=1447350883",
"website": null,
"pc_requirements": {
"minimum": "<p><strong>Minimum Requirements:<\/strong> Windows 98\/ME\/2000\/XP, 128 MB RAM, 500MHz or faster, DirectX: 7.0<\/p>"
},
"mac_requirements": [
],
"linux_requirements": [
],
"developers": [
"PopCap Games, Inc."
],
"publishers": [
"PopCap Games, Inc."
],
"demos": [
{
"appid": 3402,
"description": ""
}
],
"price_overview": {
"currency": "USD",
"initial": 499,
"final": 499,
"discount_percent": 0
},
"packages": [
135
],
"package_groups": [
{
"name": "default",
"title": "Buy Hammer Heads Deluxe",
"description": "",
"selection_text": "Select a purchase option",
"save_text": "",
"display_type": 0,
"is_recurring_subscription": "false",
"subs": [
{
"packageid": 135,
"percent_savings_text": "",
"percent_savings": 0,
"option_text": "Hammer Heads Deluxe - $4.99",
"option_description": "",
"can_get_free_license": "0",
"is_free_license": false,
"price_in_cents_with_discount": 499
}
]
}
],
"platforms": {
"windows": true,
"mac": false,
"linux": false
},
"categories": [
{
"id": 2,
"description": "Single-player"
}
],
"genres": [
{
"id": "4",
"description": "Casual"
}
],
"screenshots": [
{
"id": 0,
"path_thumbnail": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000564.600x338.jpg?t=1447350883",
"path_full": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000564.1920x1080.jpg?t=1447350883"
},
{
"id": 1,
"path_thumbnail": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000565.600x338.jpg?t=1447350883",
"path_full": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000565.1920x1080.jpg?t=1447350883"
},
{
"id": 2,
"path_thumbnail": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000566.600x338.jpg?t=1447350883",
"path_full": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000566.1920x1080.jpg?t=1447350883"
},
{
"id": 3,
"path_thumbnail": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000567.600x338.jpg?t=1447350883",
"path_full": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000567.1920x1080.jpg?t=1447350883"
},
{
"id": 4,
"path_thumbnail": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000568.600x338.jpg?t=1447350883",
"path_full": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/0000000568.1920x1080.jpg?t=1447350883"
}
],
"release_date": {
"coming_soon": false,
"date": "Aug 30, 2006"
},
"support_info": {
"url": "",
"email": ""
},
"background": "http:\/\/cdn.akamai.steamstatic.com\/steam\/apps\/3400\/page_bg_generated_v6b.jpg?t=1447350883"
}
}
}
That is the json block returned for accessing appid 3400. Note how it's appid is located inside of file itself.
In order to generate classes for this, I made a formatted version of that based off the unofficial storefront api documentation. Then I used that to generate the container classes shown below.
public class Appid
{
public bool success { get; set; }
public Data data { get; set; }
}
public class Data
{
public string type { get; set; }
public string name { get; set; }
public int steam_appid { get; set; }
public int required_age { get; set; }
public int[] dlc { get; set; }
public string detailed_description { get; set; }
public string about_the_game { get; set; }
public Fullgame fullgame { get; set; }
public string supported_languages { get; set; }
public string header_image { get; set; }
public string website { get; set; }
public Pc_Requirements pc_requirements { get; set; }
public Mac_Requirements mac_requirements { get; set; }
public Linux_Requirements linux_requirements { get; set; }
public string[] developers { get; set; }
public Demos demos { get; set; }
public Price_Overview price_overview { get; set; }
public int[] packages { get; set; }
public Package_Groups[] package_groups { get; set; }
public Platforms platforms { get; set; }
public Metacritic metacritic { get; set; }
public Category[] categories { get; set; }
public Screenshot[] screenshots { get; set; }
public Movie[] movies { get; set; }
public Recommendations recommendations { get; set; }
public Achievements achievements { get; set; }
public Release_Date release_date { get; set; }
}
public class Fullgame
{
public int appid { get; set; }
public string name { get; set; }
}
public class Pc_Requirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class Mac_Requirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class Linux_Requirements
{
public string minimum { get; set; }
public string recommended { get; set; }
}
public class Demos
{
public int appid { get; set; }
public string description { get; set; }
}
public class Price_Overview
{
public string currency { get; set; }
public int initial { get; set; }
public int final { get; set; }
public int discount_precent { get; set; }
}
public class Platforms
{
public bool windows { get; set; }
public bool mac { get; set; }
public bool linux { get; set; }
}
public class Metacritic
{
public int score { get; set; }
public string url { get; set; }
}
public class Recommendations
{
public int total { get; set; }
}
public class Achievements
{
public int total { get; set; }
public Highlighted[] highlighted { get; set; }
}
public class Highlighted
{
public string name { get; set; }
public string path { get; set; }
}
public class Release_Date
{
public bool coming_soon { get; set; }
public string date { get; set; }
}
public class Package_Groups
{
public string name { get; set; }
public string title { get; set; }
public string description { get; set; }
public string selection_text { get; set; }
public string save_text { get; set; }
public int display_type { get; set; }
public string is_recurring_subscription { get; set; }
public Sub[] subs { get; set; }
}
public class Sub
{
public int packageid { get; set; }
public string percent_savings_text { get; set; }
public int percent_savings { get; set; }
public string option_text { get; set; }
public string option_description { get; set; }
}
public class Category
{
public int id { get; set; }
public string description { get; set; }
}
public class Screenshot
{
public int id { get; set; }
public string path_thumbnail { get; set; }
public string path_full { get; set; }
}
public class Movie
{
public int id { get; set; }
public string name { get; set; }
public string thumbnail { get; set; }
public Webm webm { get; set; }
}
public class Webm
{
public string _480 { get; set; }
public string max { get; set; }
}
Now onto the code, the function takes in a long and should return a Data object. However, instead of deserializing, it returns a null. I have checked to make sure the json is actually getting to the code. It is coming in fine.
//Steam rest stuff always returns with one object.
//This it to keep me writing 10 classes that do essentially the same thing
//And before you ask, yes, I have tried doing this without this class.
//Still didn't work.
public class RootObject<T>
{
public T response { get; set; }
}
public static Data GetGameData(long appid)
{
//Only thing different about this function except for the fact that it's also static
RestClient storeClient = new RestClient("http://store.steampowered.com/api/");
RestRequest restReq = new RestRequest("appdetails/", Method.GET);
restReq.AddParameter("appids", appid);
restReq.RequestFormat = DataFormat.Json;
restReq.OnBeforeDeserialization = resp =>
{
//This was done as an attempt to fix it.
//It makes the appid's in the content into {"appId":{
//EX: {"400":{ -> {"appId":{
resp.Content = Regex.Replace(resp.Content, "{\"\\d+\":{", "{\"appId\":{");
};
IRestResponse<RootObject<Appid>> response = storeClient.Execute<RootObject<Appid>>(restReq);
Appid trueRes = response.Data.response;
return trueRes.data;
}
Quick note, the function was altered but only to work in a static context.
The edit was noted in code.
Things I've tried
Explicitly specifying that the file is a json file.
Changing the appid class names to a common class name.
Using Json.Net as the deserializer.
Removing the "success": true item.
Using [DeserializeAs(Name = "appId")] in the appid class.
Using a non generic version of RootObject
Tried using Dictionary<string, Appid> instead of RootObject<Appid>
Edit:
For some extra information I did some testing on the methods.
I remade the object carrying classes using appid 4000 and put that into json to sharp converter. Then I wrote a small bit of code that tested if the data was null.
static void TestIfFetched(long appid)
{
Console.Write($"{appid}\t:");
Data data = GetGameData(appid);
if (data == null)
{
Console.WriteLine("Failed to get data.");
}
else
{
Console.WriteLine("Data fetched successfully.");
}
}
The result was this when testing 4000 and 400.
4000 :Failed to get data.
400 :Failed to get data.
So it seems even using data specifically designed for that game, it still fails to parse.
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
RestClient storeClient = new RestClient("https://store.steampowered.com/api/");
RestRequest restReq = new RestRequest("appdetails/", Method.GET);
restReq.AddParameter("appids", appid);
restReq.RequestFormat = DataFormat.Json;
var response = storeClient.Execute<dynamic>(restReq);
JObject jObject = JObject.Parse(response.Content);
var details = jObject[appid].Value<JObject>().ToObject<Appid>();
The above worked for me. The JObject allows you to pass the appid as a parameter and then parse your object from there.

using DataContractJsonSerializer knowntype

I am trying to deserealize json:
Classes is generated by json2sharp
But it throws exception:
Element ": Data" contains data from a data type that maps to the name
"http://schemas.datacontract.org/2004/07/TMSoft.CryptoDoc.Gu45:Gu45".
The deserializer is no information of any type, are matched with the
same name. Use DataContractResolver or add type that matches "Gu45",
the list of known types, such as using KnownTypeAttribute attribute or
by adding it to the list of known types passed to
DataContractSerializer.
How to fix it?
namespace json
{
class Program
{
static void Main(string[] args)
{
string json = System.IO.File.ReadAllText(#"D:\Json.txt");
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RootObject));
var account = serializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
}
}
public class Branch
{
public string Code { get; set; }
public string Name { get; set; }
}
public class Direction
{
public object Code { get; set; }
public string Name { get; set; }
}
public class Org
{
public string Code { get; set; }
public string Name { get; set; }
}
public class Wagon
{
public string Comment { get; set; }
public object NoteTimeString { get; set; }
public string Number { get; set; }
public string OwnerCode { get; set; }
public string StateString { get; set; }
}
public class Data
{
public string __type { get; set; }
public Branch Branch { get; set; }
public string DeliveryTimeString { get; set; }
public Direction Direction { get; set; }
public string EsrCode { get; set; }
public int GU45Type { get; set; }
public object ManeuverTime { get; set; }
public string Number { get; set; }
public Org Org { get; set; }
public object ParkName { get; set; }
public object ParkNum { get; set; }
public string RailwayName { get; set; }
public string RegistrationDateTimeString { get; set; }
public object Span { get; set; }
public string StationName { get; set; }
public string TakingTimeString { get; set; }
public object TrackNum { get; set; }
public object TrackNumAddition { get; set; }
public object WagonNote { get; set; }
public List<Wagon> Wagons { get; set; }
}
public class Body
{
public Data Data { get; set; }
public List<int> Signature { get; set; }
}
public class RootObject
{
public Body Body { get; set; }
public int Revision { get; set; }
public int State { get; set; }
public string StateDate { get; set; }
public string WosId { get; set; }
}
}
Json.txt:
{
"Body": {
"Data": {
"__type": "Gu45:#TMSoft.CryptoDoc.Gu45",
"Branch": {
"Code": "9898",
"Name": "Place"
},
"DeliveryTimeString": "07.03.2014 10:00:00",
"Direction": {
"Code": null,
"Name": "Test"
},
"EsrCode": "320007",
"GU45Type": 2,
"ManeuverTime": null,
"Number": "1",
"Org": {
"Code": "1860",
"Name": "Test"
},
"ParkName": null,
"ParkNum": null,
"RailwayName": "Test",
"RegistrationDateTimeString": "07.03.2014",
"Span": null,
"StationName": "Test",
"TakingTimeString": "07.03.2014 12:00:00",
"TrackNum": null,
"TrackNumAddition": null,
"WagonNote": null,
"Wagons": [
{
"Comment": "РЕМТ",
"NoteTimeString": null,
"Number": "44916989",
"OwnerCode": "22",
"StateString": "0"
}
]
},
"Signature": [
48,
106
]
},
"Revision": 1966,
"State": 2,
"StateDate": "2014-03-07T12:48:03Z",
"WosId": "15805729"
}
I had similar experience in my previous projects with DataContractJsonSerializer. it seems that "__type" field has a special meaning for DataContractJsonSerializer.
This is one of the main reasons that I use Json.net
it matters only if it's the first property in the object but if it has any other positions it works and exceptions is not thrown. you can try it but changing __type position below the branch property in Json.txt. I don't know if it's the case and you can find a workaround.
I haven't tried this solution but it worth to give it a try:
hope it helps

Deserializing a complex JSON object

I use JavaScript.Serializer.Deserializer to deserialize a complex JSON object, as below:
{
"name": "rule 1",
"enabled": true,
"conditions": [{
"type": "time",
"time": "17:23:10",
"days": "125"
}, {
"type": "sensor",
"uid": "10.2.0.1",
"setpoint1": 12,
"setpoint2": 18,
"criterion": 1
}, {
"type": "sensor",
"uid": "10.3.0.1",
"setpoint1": 12,
"setpoint2": 18,
"criterion": 2
}],
"actions": {
"period": 100,
"single": false,
"act": [{
"type": "on",
"uid": "10.1.0.1"
}, {
"type": "sms",
"message": "Hello World"
}]
}
}
And I want to convert it to some classes, like below:
public class Rule
{
public string name { get; set; }
public bool enabled { get; set; }
public List<Condition> conditions { get; set; }
public List<Action> actions { get; set; }
}
public class Condition
{
public string type { get; set; }
public string uid { get; set; }
public DateTime? time { get; set; }
public string days { get; set; }
public double setpoint1 { get; set; }
public double setpoint2 { get; set; }
public int criterion { get; set; }
}
public class Action
{
public int period { get; set; }
public bool single { get; set; }
public List<Act> act { get; set; }
}
public class Act
{
public string type { get; set; }
public string uid { get; set; }
public string message { get; set; }
}
The deserialization snippet:
json = new JavaScriptSerializer();
Rule rule = (json.Deserialize<Rule>(jsonStr));
If I simplify the Rule class and declare conditions and actions as simple strings, it works fine.
But if I use the classes like above, it throws an exception:
Cannot convert object of type 'System.String' to type 'System.Collections.Generic.List`1[IoTWebApplication.Condition]'
The structure you create does not fit to the JSON you posted.
It should look like
public class Rule
{
public string name { get; set; }
public bool enabled { get; set; }
public Condition[ ] conditions { get; set; }
public Actions actions { get; set; }
}
public class Actions
{
public int period { get; set; }
public bool single { get; set; }
public Act[ ] act { get; set; }
}
public class Act
{
public string type { get; set; }
public string uid { get; set; }
public string message { get; set; }
}
public class Condition
{
public string type { get; set; }
public string time { get; set; }
public string days { get; set; }
public string uid { get; set; }
public int setpoint1 { get; set; }
public int setpoint2 { get; set; }
public int criterion { get; set; }
}
It is (in most cases) very easy in VS to get the classes direct out of the JSON
Copy JSON to clipboard
In VS EDIT/Special Paste/Paste JSON as Classes (the code above was created by this)
The problem was that the inner (nested) json was quoted and therefore was processed as a string. So when I removed the quotes, it worked fine:
json = new JavaScriptSerializer();
Rule rule = (json.Deserialize<Rule>(jsonStr));

Deserializing an array of different object types

Using the Json.NET library, I'm having trouble deserializing some json returned as an array. The json is an array containing some paging information as an object and array of country objects. Here's a sample of the returned json:
[
{
"page": 1,
"pages": 6,
"per_page": "50",
"total": 262
},
[
{
"id": "ABW",
"iso2Code": "AW",
"name": "Aruba",
"region": {
"id": "LCN",
"value": "Latin America & Caribbean (all income levels)"
},
"adminregion": {
"id": "",
"value": ""
},
"incomeLevel": {
"id": "NOC",
"value": "High income: nonOECD"
},
"lendingType": {
"id": "LNX",
"value": "Not classified"
},
"capitalCity": "Oranjestad",
"longitude": "-70.0167",
"latitude": "12.5167"
}
]
]
I am attempting to deserialize to the following types:
class CountriesQueryResults
{
public PagingInfo PageInfo { get; set; }
public List<CountryInfo> Countries { get; set; }
}
class PagingInfo
{
public int Page { get; set; }
public int Pages { get; set; }
[JsonProperty("per_page")]
public int ResultsPerPage { get; set; }
public int Total { get; set; }
}
class CountryInfo
{
public string Id { get; set; }
public string Iso2Code { get; set; }
public string Name { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
public string CapitalCity { get; set; }
public CompactIdentifier Region { get; set; }
public CompactIdentifier AdminRegion { get; set; }
public CompactIdentifier IncomeLevel { get; set; }
public CompactIdentifier LendingType { get; set; }
}
class CompactIdentifier
{
public string Id { get; set; }
public string Value { get; set; }
}
I am calling DeserializeObject as so:
var data = JsonConvert.DeserializeObject<List<CountriesQueryResults>>(response);
I am getting the following error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'CountriesQueryResults' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I have been trying to get the answer from the documentation but I can't seem to figure it out. Any help would be appreciated.
Since your json is like this [ {....} , [{....}] ], You can only deserialize it to an object array(Where first item is an object and second, another array).
This simplest way I think to convert it to a c# object is:
var jArr = JArray.Parse(jsonstr);
var pageInfo = jArr[0].ToObject<PagingInfo>();
var countryInfos = jArr[1].ToObject<List<CountryInfo>>();
Class definitions would be:
public class PagingInfo
{
public int page { get; set; }
public int pages { get; set; }
[JsonProperty("per_page")]
public int ResultsPerPage { get; set; }
public int total { get; set; }
}
public class Region
{
public string id { get; set; }
public string value { get; set; }
}
public class AdminRegion
{
public string id { get; set; }
public string value { get; set; }
}
public class IncomeLevel
{
public string id { get; set; }
public string value { get; set; }
}
public class LendingType
{
public string id { get; set; }
public string value { get; set; }
}
public class CountryInfo
{
public string id { get; set; }
public string iso2Code { get; set; }
public string name { get; set; }
public Region region { get; set; }
public AdminRegion adminregion { get; set; }
public IncomeLevel incomeLevel { get; set; }
public LendingType lendingType { get; set; }
public string capitalCity { get; set; }
public string longitude { get; set; }
public string latitude { get; set; }
}
PS: You can change the property names' first char to Uppercase if you want. I used http://json2csharp.com/ to automatically generate those classes.

Categories

Resources