Weird JSON Parsing situation with C# - c#

I have a very strange situation with a customer's JSON. They send an array of objects named as the ID (which is a number) :
Instead of the expected object name allowing for a simple parsing, such as "amenity".
How can we parse this into a List of objects containing ID and Name? Here's the exact JSON text:
"amenities":{
"2194":{
"id":"2194",
"name":"Breakfast for 2"
},
"2192":{
"id":"2192",
"name":"Free WiFi"
}
}
And there are other case when we have more fields , not only id, and name inside each object
"amenities":{
"2194":{
"id":"2194",
"name":"Breakfast for 2",
"validto" : "2022-10-30"
},
"2192":{
"id":"2192",
"name":"Free WiFi",
"validto" : "2022-10-30"
}
}
Thank you all!!!

You need two classes, one to be the main(Class1) where the json will be converted into and another class(Class2) for the object in the array. Then you can convert the dictionary in the main into a List of Class2 values of the dictionary.
public class MyClass1{
public Dictionary<string,MyClass2> amenities;
}
public class MyClass2{
public string id;
public string name;
public string validto;
}
First deserialize into MyClass1, then get the Values from the Dictionary and turn into List.
List<MyClass2> list = JsonConvert.DeserializeObject<MyClass1>(jsonstring).amenities.Values.ToList()

Related

Deserialize JSON array into C# Structure with RestSharp

I am dynamically taking different JSON structures into various C# structures, using RestSharp and IRestResponse<T> response = client.Execute<T>(request). But, one particular JSON result is giving me trouble, where it starts and ends with brackets...
My JSON starts and ends with "[" and "]" characters:
[
{
"first": "Adam",
"last": "Buzzo"
},
{
"first": "Jeffrey",
"last": "Mosier"
}
]
I've created this class structure:
public class Person
{
public string first { get; set; }
public string last { get; set; }
}
public class Persons
{
public List<Person> person { get; set; }
}
I use RestSharp within a method to deserialize dynamically into my Persons type T...
IRestResponse<T> response = client.Execute<T>(request);
return response;
The problem is that when T is Persons I get this error on the client.Execute line:
Unable to cast object of type 'RestSharp.JsonArray' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.
I also tried with Json.Net and got this error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Persons' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.
Given the initial "[" character, I tried deserializing into a List of Persons. That stopped the error message and I had the right number of "Person" records BUT they were all null. (I confirmed casing of names was identical.) I also don't really want to use a List collection when there is always only one element to the array from the target server and so binding to "Persons" makes more sense than "List".
What is the correct way to deserialize this JSON into Persons and still within the scope of my dynamic IRestResponse<T> response = client.Execute<T>(request) methodology?
As mentioned in the comments, your json holds an array of persons. Therefore the target structure to deserialize to should match that.
Either use:
var response = client.Execute<List<Person>>(request);
or if you prefer the Persons class, change it to
public class Persons : List<Person>
{
}

How to deserialize json and retrieve specific property values in c#

I'm quite new to JSON with C# (Using VS2017). Tried accessing each element of this object via code (e.g. Getting the strings "Obj1", "Obj2", "Obj3" and then the values of each of their members (Id and name).
I do not know in advance how many "ObjX" there will be or their names. I'm trying to load this list into some class and then convert it into a CSV (or SQL inserts).
Tried with JSON.net and JsonFx but I think my skills are just not strong enough to understand how to do this other than brute-force string manipulation functions. Can anyone help?
{
"OBJ1":{
"id":1,
"name":"Name1",
},
"OBJ2":{
"id":2,
"name":"Name2",
},
"OBJ3":{
"id":3,
"name":"Name3",
}
}
Create a class, MyClass with two properties, int Id and string Name.
public class MyClass
{
public int Id {get; set;}
public string Name {get;set;}
}
Then, depending on how you want to do it you can either deserilize it to a Dictionary or create a MyClassRoot object with three MyClass properties.
I recommend the Dictionary approach.
If you use the Dictionary approach your code will still work if more properties gets added to the JSON. If you use the MyClassRoot solution you will need to add the corresponding property to the MyClassRoot if the json updates.
Then with JSON.Net you can deserialize the object like this.
var result = JsonConvert.DeserializeObject<Dictionary<string, MyClass>>(json);
The "OBJ1", "OBJ2" and so on will then be keys in the dictionary and you can access the values like this:
var obj1 = result["OBJ1"];
var obj1Name = obj1.Name;
var obj1Id = obj1.Id;
To get all the MyClass objects to a list, simply do the following:
var list = result.ToList();
MyClassRoot approach(not recommended at all, just a POC):
public class MyClassRoot
{
public MyClass Obj1 {get;set;}
public MyClass Obj2{get;set;}
public MyClass Obj3{get;set;}
}
var result = JsonConvert.DeserializeObject<MyClassRoot>(json);
var obj1Name = result.Obj1.Name;
var obj1Id = result.Obj1.Id;

Deserialize object with DataContractJsonSerializer and map it to a list

I'm already knew how to deserialize a JSON array using DataContractJsonSerializer, but now I have a JSON object, it has a key called items and the value is an array.
for example, the JSON string is { name: "someString", items: [1, 2, 3] }
Now I want to know is there any built-in method to convert this object to a custom class derived from List<T>, for example to the following class:
[DataContract] // This is not working, you can't apply DataContract attribute to a List<T>
// [ItemsCollectionIsIn("items")]
public class MyObject : List<int>
{
[DataMember]
public string name;
}
I had tried [CollectionDataContract] attribute with its ItemName set to "items", but seems DataContractJsonSerializer just ignores ItemName property and serializes/deserializes the object to/from an array.
Now I can implement IList<T> on my class and return values from a internal list, or I think I can write one class for JSON object contract and the other one derived from List then populate values manually, is there any better ways?
I'm working on Windows Phone LongListSelector so I need a GroupedList (List<List<T>>).
Or if JSON.Net can do it more easier please give me some hint.
I think you modeled your type incorrectly, the array is a property in the root object. Try it this way:
[DataContract]
public class MyObject
{
[DataMember]
public string name;
[DataMember]
public List<int> items;
}

Deserialization of not so well formated json

I need help or some inspiration for some strange json deserialization.
This is the json I recieve from a service (can't change it, its an external service):
{
"status":"OK",
"statuscode":200,
"payload":{
"solarforecast":{
"5876":{
"2014-06-06 23:00:00":{
"bh":0,
"dh":0
},
"2014-06-07 00:00:00":{
"bh":0,
"dh":0
},
[...]
}
}
}
I made a call to get values for a object with id 5876.
So if I made a call for object with id 1254, the json changed this way:
[...]
"solarforecast":{
"1254":{
"2014-06-06 23:00:00":{
[...]
I now want to create an c# object from this json code with help of Newton ;) .
My frist Problem is that the property name (aka object id) is different for any object call and its a number.
My second problem are the sub objects with undefinded count. I think in a well formed json object it has to be somethink like this (see "[" brackets):
"solarforecast":{
"5876":[
"2014-06-06 23:00:00":{
"bh":0,
"dh":0
},
"2014-06-07 00:00:00":{
"bh":0,
"dh":0
},
[...]
]
}
Has anybody a trick or solution how to well deserialize this json into a proper c# class?
I try to get somethink like that as result:
public class Payload
{
[JsonProperty("solarforecast")]
public SolarForecast SolarForecast;
}
public class SolarForecast
{
[JsonProperty("???")]
public IEnumerable<SolarForecastTimeSet> SomeObjectID;
}
public class SolarForecastTimeSet
{
[JsonProperty("???")]
public decimal TimeStamp;
[JsonProperty("dh")]
public decimal DiffusRadiationHorizontal;
[JsonProperty("bh")]
public decimal DirectRadiationHorizontal;
}
Thanks for your help!!
Steffen
Ok figured out how it will work!
Object tree has to be:
public class Payload
{
[JsonProperty("solarforecast")]
public Dictionary<int, Dictionary<DateTime, SolarForecastTimeSet>> SolarForecast;
}
public class SolarForecastTimeSet
{
[JsonProperty("dh")]
public decimal DiffusRadiationHorizontal;
[JsonProperty("bh")]
public decimal DirectRadiationHorizontal;
}
Thanks #andyp for his dictionary hint!

How to deserialize variable size JSON string with variable names

Deserializing a small, fixed size, fixed structure, with fixed field names, JSON string is easy: Just define a class that contains all the fields (with correct types and names, all known at compile time).
Deserializing a variable-size of repeating nested pairs, is somewhat more challenging but can be done with the help of a List<> inside the class.
But what do I do when the name of the fields are unknown at compile time? e.g.:
{
"container":{
"GD01AB491103":{
"field_id1":11,
"field_id2":12,
"field_id3":13,
"field_id4":"fourteen"
},
"DC01AB491103":{
"field_id1":21,
"field_id2":22,
"field_id3":23,
"field_id4":"twenty four"
},
"GH01AB451101":{
"field_id1":31,
"field_id2":32,
"field_id3":33,
"field_id4":"thirty four"
}
.
.
.
},
"terminator"
}
How to deserialize such a string?
(preferably with .NET's JavaScriptSerializer but if it's too weak/incapable, I might need to resort to something else)
Edit: To clarify the nature of the challenge: In the example above, in order to define a class:
public class ??????
{
public int field_id1 {get;set;}
public int field_id2 {get;set;}
public int field_id3 {get;set;}
public string field_id4 {get;set;}
}
I need to query the JSON string first, then at runtime build classes (reflection?) with these variable-name class objects in it? Looks too cumbersome... Perhaps there is a saner way?
Or maybe the class/field names are irrelevant to .NET's JavaScriptSerializer and all matters is the type? (and correct structure of course)
You can do this probably more simply than you think.. your ?????? class can be anything..
public class GenericObject
{
public int field_id1 {get;set;}
public int field_id2 {get;set;}
public int field_id3 {get;set;}
public string field_id4 {get;set;}
}
and then deserialize the root of the object graph into an object that contains a Dictionary<string,GenericObject>...
public class SomeContainer
{
public Dictionary<string,GenericObject> container {get;set;}
}
you can then loop over the values of the dictionary if you don't care about the names of the keys.

Categories