Strange Json deserialize [duplicate] - c#

This question already has answers here:
How can I deserialize a child object with dynamic (numeric) key names?
(2 answers)
Closed 2 years ago.
I try to make a connection with RouteXL but in the api response i get a json who is maybe invalid.
From the tag route he send a sort of array starting with a string index. Normally i convert this to a class (http://json2csharp.com) but with this json i get a invalid class structure because of the string index.
Before i go to split it by myself. You guys have a better solution?
With regards,
SirNirido
json:
{
"id": "6VTa8zH8",
"count":5,
"feasible":true,
"route": {
"0": { "name": "StartLocatie", "arrival":0, "distance":0},
"1": { "name": "58", "arrival":28, "distance":47.7},
"2": { "name": "57", "arrival":42, "distance":65.3},
"3": { "name": "56", "arrival":47, "distance":68.5},
"4": { "name": "StartLocatie", "arrival":61, "distance":87.1}}}

Thanks #JonSkeet it works like a charm.
It's a hard one for google. But if anyone ever have the sameproblem here is my new class schema
class Results
{
public string id { get; set; }
public int count { get; set; }
public bool feasible { get; set; }
public Dictionary<string, RouteResult> route { get; set; }
}
public class RouteResult
{
public string index { get; set; }
public string name { get; set; }
public int arrival { get; set; }
public double distance { get; set; }
}

Related

Can I make deserialization fail for mapping a quoted number to a int? [duplicate]

This question already has answers here:
JSON Deserialization - String Is Automatically Converted To Int
(2 answers)
Closed 25 days ago.
I have the following json payload:
{
"s": "hfhryru567riuey4",
"t": 1643184327,
"b": "1c4736b4-db30-43a5-ba49-d9e5c1904c05",
"p": "1-1",
"a": "V"
}
Which I deserialize to the following class, using newtonsoft:
public class ValidationModel
{
[JsonRequired]
[Required(AllowEmptyStrings = false)]
public string s { get; set; }
[JsonRequired]
public int t { get; set; }
[JsonRequired]
public System.Guid b { get; set; }
[JsonRequired]
[Required(AllowEmptyStrings = false)]
public string p { get; set;}
[JsonRequired]
[Required(AllowEmptyStrings = false)]
public string a { get; set; }
}
The problem is, that when I try to give the following json, where t is in a string, I want it to fail:
{
"s": "hfhryru567riuey4",
"t": "1643184327",
"b": "1c4736b4-db30-43a5-ba49-d9e5c1904c05",
"p": "1-1",
"a": "V"
}
But right now, it just seems like it is casting t to from a string to a number.
I need it to fail in this case, since I am using the deserialization to confirm that the payload is in the right form.
How can I do this?
I would use a json constructor
public class ValidationModel
{
public int t { get; set; }
// all your another properties
[JsonConstructor]
public ValidationModel (JToken t)
{
if (t.Type == JTokenType.Integer) this.t = (int)t;
else throw new JsonException("t property should be int type");
}
}

Deserialize dynamic JSON data to C# object [duplicate]

This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Using JSON.NET to read a dynamic property name
(1 answer)
Create a strongly typed c# object from json object with ID as the name
(1 answer)
Closed 4 years ago.
I have a JSON string like this:
{
"ProfileChange": 5,
"profileId": "anId",
"profileChanges": [
{
"changeType": "fullProfileUpdate",
"profile": {
"_id": "g3fwerfgscsdadad",
"rvn": 7,
"wipeNumber": 5,
"accountId": "gw4gefsdfswfwfwdqe",
"profileId": "anId",
"version": "latestUpdate",
"items": {
"abc-123": {
"templateId": "default",
"attributes": {
"max": 0,
"bonus": 1,
"seen": 1,
"xp": 0,
"variants": [],
"favorite": false
},
"quantity": 1
},
"zxc-456": {
"templateId": "default",
"attributes": {
"max": 0,
"bonus": 1,
"seen": 1,
"xp": 0,
"variants": [],
"favorite": false
},
"quantity": 1
}
}
}
}
]
}
I want to deserialize it to a C# object, and here is my code:
class Model
{
[JsonProperty("ProfileChange")] public long ProfileChange { get; set; }
[JsonProperty("profileId")] public string ProfileId { get; set; }
[JsonProperty("profileChanges")] public List<ProfileChange> ProfileChanges { get; set; }
}
public class ProfileChange
{
[JsonProperty("changeType")] public string ChangeType { get; set; }
[JsonProperty("profile")] public Profile Profile { get; set; }
}
public class Profile
{
[JsonProperty("_id")] public string Id { get; set; }
[JsonProperty("rvn")] public long Rvn { get; set; }
[JsonProperty("wipeNumber")] public long WipeNumber { get; set; }
[JsonProperty("accountId")] public string AccountId { get; set; }
[JsonProperty("profileId")] public string ProfileId { get; set; }
[JsonProperty("version")] public string Version { get; set; }
[JsonProperty("items")] public Items Items { get; set; }
}
public class Items
{
public List<IDictionary<string, ItemDetails>> Item { get; set; }
}
public class ItemDetails
{
[JsonProperty("templateId")] public string TemplateId { get; set; }
}
And then I implement it in my main implementation like this:
var obj = JsonConvert.DeserializeObject<Model>(json);
And it does deserialize most of the data, however, the part I am struggling to deserialize is the Items one. Since they are generated dynamically, I want to create a dictionary of the items, with string for the entry and ItemDetails for the details of it.
I have used Dictionary and also made it a list, since there are multiple items, but it still is null. I also tried non-list, didn't return anything. Only null. All other details are fine, except the dictionary and dynamically generated JSON data.
I need help to fix the issue with deserializer returning null for the Items Dictionary.

Deserializing Many Json Objects into List - C# [duplicate]

I have this JSON and I cannot figure out how to convert it to a List of objects in C#.
Here is the JSON:
{
"2": {
"sell_average": 239,
"buy_average": 238,
"overall_average": 240,
"id": 2
},
"6": {
"sell_average": 184434,
"buy_average": 182151,
"overall_average": 189000,
"id": 6
},
"8": {
"sell_average": 11201,
"buy_average": 1723,
"overall_average": 180,
"id": 8
}
}
And the code I've tried using:
public class ItemSummaryModel
{
public string Id { get; set; }
public ItemSummary ItemSummary { get; set; }
}
public class ItemSummary
{
public int Sell_Average { get; set; }
public int Buy_Average { get; set; }
public int Overall_Average { get; set; }
public int Id { get; set; }
}
List<ItemSummaryModel> models =
JsonConvert.DeserializeObject<List<ItemSummaryModel>>(jsonSummary);
to no avail. How can I deserialize this JSON into lists of these objects using Newtonsoft's JSON library (Json.Net)?
You can use
var dict = JsonConvert.DeserializeObject<Dictionary<int, ItemSummary>>(json);
var items = dict.Values.ToList(); //if you want a List<ItemSummary>;
public class ItemSummaryModel
{
[JsonProperty(PropertyName = "2")]
public ItemSummary Two { get; set; }
[JsonProperty(PropertyName = "6")]
public ItemSummary Six { get; set; }
[JsonProperty(PropertyName = "8")]
public ItemSummary Eight { get; set; }
}
var result = JsonConvert.DeserializeObject<ItemSummaryModel>(json);
This will technically work to get you a complex object, but I don't much like it. Having numbers for property names is going to be an issue. This being json for a single complex object will also be tricky. If it were instead a list, you could begin writing your own ContractResolver to handle mapping the number property name to an id field and the actual object to whatever property you wanted.

JSON won't deserialise fully to C# class [duplicate]

This question already has answers here:
Json.net failing to load certain properties belonging to a class object?
(2 answers)
Closed 4 years ago.
I am trying to deserialise some JSON which looks like this:
{
"Results":{
"Prediction":{
"type":"table",
"value":{
"ColumnNames":[
"HT",
"AT",
"X",
"Y",
"Z"
],
"ColumnTypes":[
"String",
"String",
"Double",
"Double",
"Double"
],
"Values":[
[
"Mum",
"Dad",
"0.172627246490883",
"0.171741768332677",
"0.65563098517644"
],
[
"Father",
"Mother",
"0.391368227731864",
"0.21270005247278",
"0.395931719795356"
]
]
]
}
}
}
}
The C# class looks like this:
public class RootObject
{
public Results Results { get; set; }
}
public class Results
{
public Prediction Prediction { get; set; }
}
public class Prediction
{
public string type { get; set; }
public Value value { get; set; }
}
public class Value
{
string[] ColumnNames { get; set; }
string[] ColumnTypes { get; set; }
string[][] Values { get; set; }
}
It deserialises up to the final property "value", which is not matched. If I turn on the error handling to see why I get the following error:
Additional information: Could not find member 'ColumnNames' on object of type 'Value'. Path 'Results.Prediction.value.ColumnNames', line 1, position 64.
I have a simple C# example which reproduces the whole problem:
var derek = #"{""Results"":{""Prediction"":{""type"":""table"",""value"":{""ColumnNames"":[""HT"",""AT"",""X"",""Y"",""Z""],""ColumnTypes"":[""String"",""String"",""Double"",""Double"",""Double""],""Values"":[[""Mum"",""Dad"",""0.172627246490883"",""0.171741768332677"",""0.65563098517644""],[""Father"",""Mother"",""0.391368227731864"",""0.21270005247278"",""0.395931719795356""]]]}}}}";
var returnedObj = JsonConvert.DeserializeObject <RootObject> (derek, settings);
I am pretty sure my class matches the JSON. Why doesn't it deserialise?
In C# properties default to private, they need to be public to be picked up by Newtonsoft/Json
public class Value
{
public string[] ColumnNames { get; set; }
public string[] ColumnTypes { get; set; }
public string[][] Values { get; set; }
}

Complex json deserialization

I have to deserialize the following json response (the Result list has variable length):
{
"ResultSet": {
"Query": "volkswagen",
"Result": [
{
"symbol": "VLKAY",
"name": "Volkswagen AG",
"exch": "PNK",
"type": "S",
"exchDisp": "OTC Markets",
"typeDisp": "Equity"
},
{
"symbol": "VOW3.DE",
"name": "Volkswagen AG",
"exch": "GER",
"type": "S",
"exchDisp": "XETRA",
"typeDisp": "Equity"
},
{
"symbol": "VOW.DE",
"name": "Volkswagen AG",
"exch": "GER",
"type": "S",
"exchDisp": "XETRA",
"typeDisp": "Equity"
}
]
}
}
What I got:
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonString = "...String is here...";
SearchObj obj = js.Deserialize<SearchObj>(jsonString);
I understand that I usually have to create a fitting obj. e.g. SearchObj which will get filled but in this case I'm not entirely sure how this object is supposed to look like. I came up with:
class Data
{
public string symbol { get; set; }
public string name { get; set; }
public string exch { get; set; }
public string type { get; set; }
public string exchDisp { get; set; }
public string typeDisp { get; set; }
}
class Container
{
public string Query { get; set; }
public List<Data> Result { get; set; }
}
class SearchObj
{
public Container ResultSet { get; set; }
}
But guess what, it's not working, I only get ResultSet = null.
Try to change your class Container as
class Container
{
public string Query { get; set; }
public Data[] Result { get; set; }
}
I have not tested it, based on my observation
I always feel bad when I answer my own question but here it goes.
Basically my idea was correct, I only made one mistake which is that I don't need the
class SearchObj
{
public Container ResultSet { get; set; }
}
Using
Container obj = js.Deserialize<Container>(jsonString);
instead of
SearchObj obj = js.Deserialize<SearchObj>(jsonString);
made the trick. Both Data[] and List<Data> in Container work btw.
Edit:
From giammins comment it seems that it is working on some machines without that change but I guess that's a case for undefined behavior.
You can use http://www.json2charp.com to create your classes.

Categories

Resources