how can I deserialize json arrays with newtonsoft?
Here my json file:
{
"one": [
{
"one":"1",
"two":"2",
"three":"3"
},
{
"one":"1",
"two":"2",
"three":"3"
}
],
"two": [
{
"one":"1",
"two":"2",
"three":"3"
}
]
}
Here is my code:
myList= JsonConvert.DeserializeObject <List<MyClass>>(jsonFile);
public class MyClass
{
public string one{ get; set; }
public string two { get; set; }
public string three { get; set; }
}
Maybe I need change in some way my json file?
Your class needs to match the structure your JSON. It should look like this:
public class Foo
{
[JsonProperty("one")]
public string One { get; set; }
[JsonProperty("two")]
public string Two { get; set; }
[JsonProperty("three")]
public string Three { get; set; }
}
public class RootObject
{
[JsonProperty("one")]
public List<Foo> One { get; set; }
[JsonProperty("two")]
public List<Foo> Two { get; set; }
}
Now it will properly deserialize:
Console.WriteLine(JsonConvert.DeserializeObject<RootObject>(json));
Try This :
`public class Foo
{
[JsonProperty("one")]
public string One { get; set; }
[JsonProperty("two")]
public string Two { get; set; }
[JsonProperty("three")]
public string Three { get; set; }
}
public class RootObject
{
[JsonProperty("one")]
public List<Foo> One { get; set; }
[JsonProperty("two")]
public List<Foo> Two { get; set; }
}`
and to deserialize object use
` RootObject _rootObject = JsonConvert.DeserializeObject<RootObject>
(jObject.ToString());`
If you want to keep your class structure you have to change your json file into this:
[
{
"one":"1",
"two":"2",
"three":"3"
},
{
"one":"1",
"two":"2",
"three":"3"
}
]
With this json file style the deserialization
myList= JsonConvert.DeserializeObject <List<MyClass>>(jsonFile);
will complete properly.
Your above json file has two arrays in it. Because of that the deserialization will fail.
That is no JSON array, it is an object with two array properties.
Use http://json2csharp.com:
public class YourClass
{
public string one { get; set; }
public string two { get; set; }
public string three { get; set; }
}
public class RootObject
{
public List<YourClass> one { get; set; }
public List<YourClass> two { get; set; }
}
(Don't we still have a canonical question for this? Every day the same...)
You should deserialize it as a Dictionary<string, MyClass[]>
var test = "{ \"one\": [ { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" }, { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" } ], \"two\": [ { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" } ] }";
var testar = JsonConvert.DeserializeObject <Dictionary<string, MyClass[]>>(test);
This would work out of the box if there is more keys added like Forth, Fifth and so on.
Related
I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());
I'm trying to deserialize a Json string that has an array with no containing brackets.
{ "id": "983f90j30909j3f",
"moreInfo": {
"info193802": { ... },
"info920938": { ... },
"info849028": { ... }
}
}
This "moreInfo" is an array of items with dynamic keys and does not have square brackets telling that it's an array.
I've tried to deserialize it with Newtonsoft.Json normally ( JsonConvert.DeserializeObject<rootObject>() ) but since this json array isn't really an array it throws an error. Here is my class:
public class RootObject
{
public string Id { get; set; }
public MoreInfo MoreInfo { get; set; }
}
public class MoreInfo
{
public List<Info> InfoList{ get; set; }
}
public class Info
{
properties...
}
How do I go about deserializing this?
Update the root object to use IDictionary<string, Info>
public class RootObject {
public string Id { get; set; }
public IDictionary<string, Info> MoreInfo { get; set; }
}
the dynamic keys will be the key in the dictionary.
Once parsed you access the info via the dictionary's keys
Info info = rootObject.MoreInfo["info193802"];
Newtonsoft can correctly parse the data. The data represents objects, they happen to be nested fairly deep. You can accomplish it a couple of ways, for instance:
dynamic json = JsonConvert.DeserializeObject(response);
var info = json["moreinfo:info913802:example"].Value;
Your other option would be to use Visual Studio, let it create an object you can deserialize to.
Edit
Paste Special
As JSON
Output would be:
public class Rootobject
{
public string id { get; set; }
public Moreinfo moreInfo { get; set; }
}
public class Moreinfo
{
public Info193802 info193802 { get; set; }
public Info920938 info920938 { get; set; }
public Info849028 info849028 { get; set; }
}
public class Info193802
{
public string Example { get; set; }
}
public class Info920938
{
public string Example { get; set; }
}
public class Info849028
{
public string Example { get; set; }
}
The source JSON I used was yours, with one exception:
{ "id": "983f90j30909j3f",
"moreInfo": {
"info193802": { "Example" : "Blah" },
"info920938": { "Example" : "Blah" },
"info849028": {"Example" : "Blah" }
}
}
I've popped consuming a WebServer returning the Json bellow, and I'm not able to convert it to an object.
Json
{
"success":true,
"data":{
"24486146360":{
"rfid":"123465789456",
"products":[
{
"sale_id":35,
"quantity":2,
"price":"1",
"total":"2",
"unit":"uni",
"sku":14
},
{
"sale_id":36,
"quantity":2,
"price":"2.5",
"total":"5",
"unit":"uni",
"sku":17
}
]
},
"24758345953":{
"rfid":"2129",
"products":[
{
"sale_id":39,
"quantity":1,
"price":"10",
"total":"10",
"unit":"ml",
"sku":19998
}
]
},
"64577015900":{
"rfid":"1934",
"products":[
{
"sale_id":40,
"quantity":1,
"price":"10",
"total":"10",
"unit":"ml",
"sku":19998
}
]
},
"56768990934":{
"rfid":"1746",
"products":[
{
"sale_id":46,
"quantity":1,
"price":"8.00",
"total":"8",
"unit":"UN",
"sku":20
}
]
}
}
}
I used json2sharp to generate a class from the JSON, I then cleaned up the class and was left with the following:
My Class create help for json2sharp
public class Consumo
{
public string rfid { get; set; }
public List<ConsumoProduto> products { get; set; }
}
public class ConsumoProduto
{
public int sale_id { get; set; }
public double quantity { get; set; }
public string price { get; set; }
public string total { get; set; }
public string unit { get; set; }
public int sku { get; set; }
}
public class RetornoConsumo
{
[JsonProperty("success")]
public bool Processado { get; set; }
[JsonProperty("data")]
public List<Consumo> Registro { get; set; }
}
My Problem
how do I convert Json to a valid object using Json.Net?
Test
I tried to do this and I could not
Dictionary<string, RetornoConsumo> _featuredArticles = JsonConvert.DeserializeObject<Dictionary<string, RetornoConsumo>>(json);
In your RetornoConsumo class, the Registro property needs to be a Dictionary<string, Consumo> not a List<Consumo>.
public class RetornoConsumo
{
[JsonProperty("success")]
public bool Processado { get; set; }
[JsonProperty("data")]
public Dictionary<string, Consumo> Registro { get; set; }
}
Then, you need to deserialize the JSON into the RetornoConsumo class:
var data = JsonConvert.DeserializeObject<RetornoConsumo>(json);
Fiddle: https://dotnetfiddle.net/vfhdXp
I have JSON returning in the following format:
{
"Items": [
{
"unique_id": "11111111111",
"rages": {
"rage_content": "Hello rage 2",
"date_stamp": "21/07/2017",
"id": 2
}
},
{
"unique_id": "2222222222",
"rages": {
"rage_content": "Hello rage 1",
"date_stamp": "21/07/2017",
"id": 1
}
}
],
"Count": 2,
"ScannedCount": 2
}
And I have the following 2 classes defined:
Items.cs:
namespace ragevent_A0._0._1
{
class Items
{
public String rage_id { get; set; }
public rage rage { get; set; }
}
}
rage.cs:
class rage
{
public String rage_content { get; set; }
public String date_stamp { get; set; }
public int id { get; set; }
}
I am using the following code in order to attempt to deseralize the JSON returned above:
List<Items> data = JsonConvert.DeserializeObject<List<Items>>(json);
However, I am not able to successfully deserialize the data due to the above error. I have tried a few solutions online, however I have not managed to find a solution which works with the format of my returned JSON. I have used a JSON formatter and it is formatted correctly, so that shouldn't be the issue.
Any help would be much appreciated!
For the posted JSON data below should be the model you need (credit: http://json2csharp.com/). There is mismatch between the property name rage_id. You can use JsonProperty attribute
public class Rages
{
public string rage_content { get; set; }
public string date_stamp { get; set; }
public int id { get; set; }
}
public class Item
{
[JsonProperty(Name="rage_id")]
public string unique_id { get; set; }
public Rages rages { get; set; }
}
public class RootObject
{
public List<Item> Items { get; set; }
public int Count { get; set; }
public int ScannedCount { get; set; }
}
Your deserialization should be
var data = JsonConvert.DeserializeObject<RootObject>(json);
I'm creating a Steam APP ( For the Steam Platform ), and i need to deserialize a JSON file.
{
"response": {
"success": 1,
"current_time": 1401302092,
"raw_usd_value": 0.245,
"usd_currency": "metal",
"usd_currency_index": 5002,
"items": {
"A Brush with Death": {
"defindex": [
30186
],
"prices": {
"6": {
"Tradable": {
"Craftable": [
{
"currency": "metal",
"value": 4,
"last_update": 1398990171,
"difference": 0.17
}
]
}
}
}
},
...
I just need to get Defindex and value. Already deserialized some simple JSON files, but i think this one is more complex.
For those who wants to know, I am using the API from BackpackTF...
Use NewtonSoft.Json And then you can use it as follows to get the data out.
dynamic json = JsonConvert.DeserializeObject(<yourstring>);
string currency = json.response.usd_currency; // "metal"
In general, what you want to do is making sure you have valid JSON (use JSON LINT for that), then get a C# class definition with Json2CSharp, then you will do something like this:
MyClass myobject=JsonConvert.DeserializeObject<MyClass>(json);
(We're assuming MyClass is based on what you got from Json2CSharp)
Then you access the values you want via the traditional C# dot notation.
Use a nuget package caller Newtonsoft.Json.5.0.8. it is on the nuget repository.
This line of code will take your json as a string, and turn it into its root object.
RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonString);
The Json you provided is slightly flawed, but im guessing that the structure of c# objects you would be looking for would be close to this:
public class Craftable
{
public string currency { get; set; }
public int value { get; set; }
public int last_update { get; set; }
public double difference { get; set; }
}
public class Tradable
{
public List<Craftable> Craftable { get; set; }
}
public class Prices
{
public Tradable Tradable{ get; set; }
}
public class Items
{
public List<int> defindex { get; set; }
public Prices prices { get; set; }
}
public class Response
{
public int success { get; set; }
public int current_time { get; set; }
public double raw_usd_value { get; set; }
public string usd_currency { get; set; }
public int usd_currency_index { get; set; }
public Items items { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}