Deserialize JSON file with different keys - c#

I have a json like this:
[
{ "Province1" : [
{ "name" : "city-1" },
{ "name" : "city-2" }
]
},
{ "Province2" : [
{ "name" : "city-1" },
{ "name" : "city-2" }
]
}
]
I want to deserialize it using NewtonsoftJson. I have tried this but the result is null:
public class City {
public string Name { get; set; }
}
var cities = JsonConvert.DeserializeObject<IEnumerable<KeyValuePair<string, List<City>>>(File.ReadAllText(#"jsonPath"));
How should I dersialize it to a class?

After fiddling around with it a bit, I've come up with this structure to deserialize it
class MyDeserializer
{
public static void Deserialize()
{
var json = "[{\"Province1\" : [{\"name\" : \"city-1\" }, {\"name\" : \"city-2\" }] }, {\"Province2\" : [{ \"name\" : \"city-1\" }, { \"name\" : \"city-2\" }] } ]";
var cities = JsonConvert.DeserializeObject<List<Dictionary<string, List<City>>>>(json);
Console.WriteLine(cities[0]["Province1"][0].Name);
}
}
class City
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
}
That gives you a dictionary for each province which seems a little unintuitive. But that's how your JSON is structured. If you want to combine all the dictionaries into one, you can do it like this
var cities = JsonConvert.DeserializeObject<List<Dictionary<string, List<City>>>>(json).SelectMany(dict => dict).ToDictionary(pair => pair.Key, pair => pair.Value);
Console.WriteLine(cities["Province1"][0].Name);

There is probably a more elegant solution to this, however this will give you a dictionary of province name with an array of city name Dictionary<string,string[]>
var dict = JArray
.Parse(input)
.Cast<JObject>()
.Select(x => x.Properties().First())
.ToDictionary(
x => x.Name,
x => x.Values().Values().Select(x => x.First.ToString()).ToArray());

I think your structure should be like this :
[
{ "Name": "Province1",
"Cities": [
{ "name": "city-1" },
{ "name": "city-2" }
]
},
{ "Name": "Province2",
"Cities": [
{ "name": "city-1" },
{ "name": "city-2" }
]
}
]
And to deserilize it :
namespace ConsoleApp2 {
public class Province {
public string Name { get; set; }
public List<City> Cities { get; set; }
}
public class City {
public string Name { get; set; }
}
public class ConsoleApp2 {
public static void Main(string[] args) {
List<Province> provinces = JsonConvert.DeserializeObject<List<Province>>(File.ReadAllText("province.json"));
}
}
}

Related

Updating an Array of Object inside a Array of Object using linq in c#

I have a JSON object like below,
[
{
"BatchId": "BAT1",
"PartialBatch": [
{
"PartialBatchID": "PAR1",
"Status": "Active"
},
{
"PartialBatchID": "PAR2",
"Status": "Inactive"
}
]
},
{
"BatchId": "BAT2",
"PartialBatch": [
{
"PartialBatchID": "PAR3",
"Status": "Active"
},
{
"PartialBatchID": "PAR4",
"Status": "Inactive"
}
]
}
]
I have another Array of Strings of PartialBatchID's
["PAR1","PAR3"]
What would be the best and most quickiest way to update the status fields to Active for the PartialBatchID's present in above array, against the main json.
Here's a way using the Newtonsoft.Json Nuget package. Now in your example the PAR1 and PAR3 are already active, but this will work:
void Main()
{
var match = new [] { "PAR1", "PAR3"};
var json = JsonConvert.DeserializeObject<JsonData[]>(main);
foreach (var b in json.SelectMany(x => x.PartialBatch).Where(x => match.Contains(x.PartialBatchID)))
{
b.Status = "Active";
}
var modifiedJson = JsonConvert.SerializeObject(json);
}
public class JsonData
{
public string BatchId { get; set; }
public Batch[] PartialBatch { get; set; }
}
public class Batch
{
public string PartialBatchID { get; set; }
public string Status { get; set; }
}
const string main = #"
[
{
'BatchId': 'BAT1',
'PartialBatch': [
{
'PartialBatchID': 'PAR1',
'Status': 'Active'
},
{
'PartialBatchID': 'PAR2',
'Status': 'Inactive'
}
]
},
{
'BatchId': 'BAT2',
'PartialBatch': [
{
'PartialBatchID': 'PAR3',
'Status': 'Active'
},
{
'PartialBatchID': 'PAR4',
'Status': 'Inactive'
}
]
}
]";

Select Filtering JArray

I have a JArray as follow:
[
{
"id": 5447,
"attributes": {
"alarm": "Mode1"
},
"deviceId": 28
},
{
"id": 5448,
"attributes": {
"alarm": "Mode1"
},
"deviceId": 28
},
{
"id": 5449,
"attributes": {
"alarm": "Mode2"
},
"deviceId": 28
}
]
how to filter by ["attributes"]["alarm"] == "Mode1" ?
I tried:
JArray _new_ja = __ja_alarm.Where(p => p["attributes"]["alarm"].ToString() == "Mode1");
it returns null?
You could just deserialize it
Given
public class Attributes {
public string alarm { get; set; }
}
public class Model {
public int id { get; set; }
public Attributes attributes { get; set; }
public int deviceId { get; set; }
}
Usage
var model = JsonConvert
.DeserializeObject<List<Model>>(input)
.FirstOrDefault(x => x.attributes.alarm == "Mode1");
Or
var result = JArray
.Parse(input)
.FirstOrDefault(x => (string) x["attributes"]["alarm"] == "Mode1")
.ToObject<Model>();
Use Where instead of FirstOrDefault If you want a list of matches

Deserializing nested JSON array inside nested JSON object in c#?

I have a json file as follows:
{
"container" : {
"cans1" :
[
{
"name" : "sub",
"ids" :
[
"123"
]
},
{
"name" : "Fav",
"ids" :
[
"1245","234"
]
},
{
"name" : "test",
"ids" :
[
"DOC12","DOC1234"
]
}
],
"ids" :
[
"1211","11123122"
],
"cans2" :
[
{
"name" : "sub1",
"ids" :
[
"123"
]
}
],
"ids" :
[
"121","11123"
]
}
I want to fetch name values sub,fav,test and ids for each cans in this json file using c#
Install nuget Newtonsoft.Json. Create next hierarchy:
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class MyClass
{
[JsonProperty("container")]
public Container Container { get; set; }
}
public class Container
{
[JsonProperty("cans1")]
public Cans[] Cans1 { get; set; }
[JsonProperty("ids")]
[JsonConverter(typeof(DecodeArrayConverter))]
public long[] Ids { get; set; }
[JsonProperty("cans2")]
public Cans[] Cans2 { get; set; }
}
public class Cans
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("ids")]
public string[] Ids { get; set; }
}
And then
JsonConvert.DeserializeObject<MyClass>(yourJsonString);
UPD
Based on comment, try this:
var des = JsonConvert.DeserializeObject<MyClass>(t);
foreach(var arr in des.Container.Where(r => r.Key.StartsWith("cans")))
{
Console.WriteLine($"{arr.Key}");
foreach(var elem in arr.Value)
{
Console.WriteLine($" {elem.Value<string>("name")}");
}
}
public class MyClass
{
[JsonProperty("container")]
public Dictionary<string, JArray> Container { get; set; }
}

JSON Object from C#

I am trying to acheive below JSON Object from c# code
{
"Animals": {
"name": "Animals",
"data": [
[
"Cows",
2
],
[
"Sheep",
3
]
]
},
"Fruits": {
"name": "Fruits",
"data": [
[
"Apples",
5
],
[
"Oranges",
7
],
[
"Bananas",
2
]
]
},
"Cars": {
"name": "Cars",
"data": [
[
"Toyota",
1
],
[
"Volkswagen",
2
],
[
"Opel",
5
]
]
}
}
I tried json2C# link and it gave me this class structure
public class Animals
{
public string name { get; set; }
public List<List<object>> data { get; set; }
}
public class Fruits
{
public string name { get; set; }
public List<List<object>> data { get; set; }
}
public class Cars
{
public string name { get; set; }
public List<List<object>> data { get; set; }
}
public class RootObject
{
public Animals Animals { get; set; }
public Fruits Fruits { get; set; }
public Cars Cars { get; set; }
}
My first problem is the classes generated by code is static (Animals,Fruits,Cars) in reality it could be more and less it is category and it may be some new categories so every time I need to create a new class for each category? how can I handle this?
Second how I populate from these classes the same structure.
Please bear with me as I am very beginner level programmer.
Try this. Create a new console application. You will need the JSON.NET library.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace ConsoleApplication7
{
class Item : List<object>
{
public Item()
{
this.Add(""); // for name;
this.Add(0); // for value;
}
[JsonIgnore]
public string Name { get { return this[0].ToString(); } set { this[0] = value; } }
[JsonIgnore]
public int Value { get { return (int)this[1]; } set { this[1] = value; } }
}
class Category
{
public string name { get; set; }
public List<Item> data { get; set; }
public Category()
{
this.data = new List<Item>();
}
}
class Program
{
static void Main(string[] args)
{
var all = new Dictionary<string, Category>
{
{
"Animals", new Category()
{
name = "Animals",
data =
new List<Item>()
{
new Item() {Name = "Cows", Value = 2},
new Item() {Name = "Sheep", Value = 3}
}
}
//include your other items here
}
};
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(all));
Console.ReadLine();
}
}
}
You don't need separate Animals, Fruits, etc. classes. They can be merged.
public class Category
{
public string name { get; set; }
public List<List<object>> data { get; set; }
}
And since the list of items in the root object can change, you should use a Dictionary<string, Category> instead of the RootObject class you had generated. Your JSON is not valid, (test it with http://jsonlint.com/), but this produces something like the first part of your example:
var dict = new Dictionary<string, Category>
{
{ "Animals", new Category
{
name = "Animals",
data = new List<List<object>>
{
new List<object> { "Cows", 2 },
new List<object> { "Sheep", 3 }
}
}
},
};
string serialized = JsonConvert.SerializeObject(dict, Formatting.Indented);
Produces the following (I'm using Json.NET for the serialization here). The other types would be similar. (see Object and Collection Initializers for more info on the list and dictionary initialization syntax I used, if you're unfamiliar with it; basically just shortcuts for their Add methods)
{
"Animals": {
"name": "Animals",
"data": [
[
"Cows",
2
],
[
"Sheep",
3
]
]
}
}
If you have a choice of what the data types should be, I think it'd be better to replace the List<object> with a class something like this, to be more clear:
public class Item
{
public string name { get; set; }
public int quantity { get; set; }
}
Install the JSON.NET library.
Then with the classes that were created:
string jsonStr = "{'Animals': {name: 'Animals', data: [['Cows', 2], ['Sheep', 3] ] },'Fruits': { name: 'Fruits', data: [['Apples', 5], ['Oranges', 7], ['Bananas', 2] ] }, 'Cars': { name: 'Cars', data: [ ['Toyota', 1], ['Volkswagen', 2], ['Opel', 5] ] } }";
RootObject Myobj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonStr);

How to deserialize a json array with unfixed name in JSON.NET

I have a question on how to deserialize a json array with unfixed name, for instance I have a json string as below.
[
{
"37414": "MP",
"weight": 1000
},
{
"21253": "Develper",
"weight": 424
},
{
"66344": "APP",
"weight": 1158
},
{
"1622": "API",
"weight": 164
}
]
I also defines a class as below and want to use JSON.NET to deserialize json string to UserTag object. Or should I change the class definition.
public class UserTag
{
// "37414"
public long Id { get; set; }
// MP
public string Name { get; set; }
// 424
public long Weight { get; set; }
}
Thanks in advance!
Are you using correct json format ?
I think you should use:
[
{
"Id" :37414,
"Name" : "MP",
"Weight": 1000
},
{
"Id" :21253,
"Name" : "Develper",
"Weight": 424
},
{
"Id": 66344,
"Name" : "APP",
"Weight": 1158
}
]
It will deserialize to:
public class UserTag
{
public int Id { get; set; }
public string Name { get; set; }
public int Weight { get; set; }
}
var result = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
foreach (var item in result)
{
foreach (var kv in item)
{
Console.WriteLine(kv.Key + ": " + kv.Value);
}
}

Categories