Read all dynamic name and value from JSON string - c#

I need to get all dynamic name and values from JSON string. I am going to create one function with JSON string parameter. that parameter JSON string name and values can change, But I need to print all names and values from that JSON string.
Example code :
json : { "data":
[{
"id": "001",
"Name": "Somu",
"Address": "Erode",
},
{
"id": "002",
"Name": "Ajal",
"Address": "USA",
}]
}
I want to Get all values from this JSON with in loop. Property name may change or increase property count.I need to get all values from passed JSON.
Expected Result : 1 st loop
Id = 001
Name =Somu
Address =Erode
2 nd loop
Id = 002
Name =Ajal
Address =USA

Using Json.Net
string json = #"{ ""data"": [ { ""id"": ""001"", ""Name"": ""Somu"", ""Address"": ""Erode"", }, { ""id"": ""002"", ""Name"": ""Ajal"", ""Address"": ""USA"", }] }";
var result = JObject.Parse(json)
["data"]
.Select(x => new
{
id = (string)x["id"],
Name = (string)x["Name"],
Address = (string)x["Address"],
})
.ToList();
or more dynamic versions
var result = JObject.Parse(json)
["data"]
.Select(x=> x.Children().Cast<JProperty>()
.ToDictionary(p=>p.Name,p=>(string)p.Value))
.ToList();
.
var result = JObject.Parse(json)["data"]
.ToObject<List<Dictionary<string,string>>>();

Related

How to update JArray values with C# and Json.NET

I'm getting an array of items from Web API (lines before this are omitted):
var cars = JArray.Parse(response.Content.ReadAsStringAsync().Result)
Inside the cars JArray it looks like this:
"cars": [{
"id": 1,
"make": "Audi",
"color": "red"
}, {
"id": 2,
"make": "Mercedes",
"color": "red"
}, {
"id": 3,
"make": "Ford",
"color": "yellow"
}]
I would like to update the color of Ford to red if Audi is also red.
How can I do that with C# and Json.NET?
The JSON you provided is not valid for me to parse, so ive made an assumption to demonstrate. which wraps your sample in a root JSON object.
You can query the JOBject using keys. i.e to access cars propery in the JSON you can use o["cars"]. With this approach you can see i use a bit of Linq to figure out if Audi is red, and if so, you can perform direct modifications to the o object and set values accordingly.
This is the most basic approach, without any further code.
void Main()
{
var json = #"
{
""cars"": [
{ ""id"": 1, ""make"": ""Audi"", ""color"": ""red"" },
{ ""id"": 2, ""make"": ""Mercedes"", ""color"": ""red"" },
{ ""id"": 3, ""make"": ""Ford"", ""color"": ""yellow"" }
]
}";
var jObject = Newtonsoft.Json.Linq.JObject.Parse(json);
var jArray = jObject["cars"] as JArray;
Console.WriteLine("Before: " + JsonConvert.SerializeObject(jObject));
var audiIsRed = jArray.Any(car => car.Value<string>("make").Equals("Audi") && car.Value<string>("color").Equals("red"));
if (audiIsRed)
{
jArray.First(c => c.Value<string>("make").Equals("Ford"))["color"] = "red";
}
Console.WriteLine("After: " + JsonConvert.SerializeObject(jObject));
}
An alternative could be making a POCO to deserialize the results, which would contain, for example a List<Car> and then you could do all modifications with C# and no JSON.NET then serialize that result back to JSON.

How to get a particular value from Json using SelectToken

I have a JSON like this
{
"Customer": {
"$type": "Dictionary`2",
"Id": "6448DE37E2F3D9588118A1950"
},
"Databases": [
{
"$type": "Pime",
"Id": 1,
"Name": "Peter",
"MobNo": 78877629,
"PAN": "SAKKJKJ",
"Defaulter": true,
},
{
"$type": "Pime",
"Id": 2,
"Name": "James",
"MobNo": 58277699,
"PAN": "NAQKJKJ",
"Defaulter": false,
},
{
"$type": "Pime",
"Id": 3,
"Name": "Norton",
"MobNo": 38877699,
"PAN": "TAKKJKJ",
"Defaulter": true,
},
]
}
I'm using a token to select the node and return the customer information whose Id=2
My code goes like this:
StreamReader r = new StreamReader("C:\TestJson\Test.db");
string json = r.ReadToEnd();
JObject o = JObject.Parse(json);
JToken result = o.SelectToken("$.Databases[?(#.Id == '2')]");
But I am getting the result as null. Am I using the wrong token in the SelectToken() method?
First of all given JSON is invalid, in database array value of Name and PAN keys should be of type string. You are missing "(double qoutes) in above json.
Second and most important thing, type of Id is an integer and in your Json Path you are trying to search with string type i.e '2', try to search Id by integer without quoute it will work.
//No single qoutes for 2.
JToken result = o.SelectToken("$.Databases[?(#.Id == 2)]");

'Accessed JObject values with invalid key value: 1. Object property name expected.'

I am trying to get JSON data from an api.
I have this json with me:
{
"elements": [
{
"id": 1,
"name": "Bob",
"address": "abc street",
"hobbies": {
"indoor": "Games, reading books",
"outdoor": ""
}
},
{
"id": 2,
"name": "Mark",
"address": "def street",
"hobbies": {
"indoor": "Games, reading books",
"outdoor": ""
}
}
]
}
I have this code with me:
using(var httpClient = new HttpClient()) {
HttpResponseMessage response = httpClient.GetAsync("api_url_here").Result;
var studentJsonString = response.Content.ReadAsStringAsync().Result;
var Jsresult = new JavaScriptSerializer().Deserialize<dynamic>(studentJsonString).ToString();
JObject jObject = JObject.Parse(Jsresult);
IEnumerable<dynamic> listDyn = jObject[0].Select(items => new StudentModel// gives error here as whole
{
id = items["id"].ToString(),
name = items["name"].ToString(),
address= items["address"].ToString()
});
}
But when I am calling the above method but it is giving me an error:
'Accessed JObject values with invalid key value: 1. Object property name expected.'
What am I missing?
Why are you deserializing twice? The result of
JavaScriptSerializer().Deserialize(customerJsonString)
is already an object. You don't need to parse it again with JObject.Parse(). You can just do
JObject jObject= JObject.Parse(customerJsonString)
Furthermore the result of JObject.Parse() is a dictionary and not an array. It has properties, which you can access by their names. For instance
jObject["elements"]
But of course, the compiler can't possibly predict, that jObject["elements"] will be an IEnumerable, so you will have to make sure of that.
jObject.Value<JArray>("elements").Select(item => ...)
This reads the property elements, of jObject as a JArray.

Convert a list of JToken to a list of one of the values

I have a list of json JTokens:
List<JToken> subjectresults = jObj[jp]["subjects"].Children().ToList();
Note that my jp is var jp = jObj.Properties().First().Name; because the name is dynamic.
Each of the tokens contains two further items, a url and a name.
I want to get a list of strings that contains just the name value, from this list of jtokens.
So that:
[0]: {{
"url": "https://openlibrary.org/subjects/science",
"name": "Science"
}}
[1]: {{
"url": "https://openlibrary.org/subjects/in_library",
"name": "In library"
}}
Becomes:
{"Science", "In library"}
I can't seem to figure out the syntax.
Or alternatively how do I skip the tokens and go right to my list.
I didn't strongly type this, because the parent property has the dynamic name, and I only needed a couple of the fields.
I suppose that subjects-property is Array:
var jObj = JObject.Parse(json);
var jp = jObj.Properties().First().Name;
var subjectresults = jObj[jp]["subjects"]
.Children()
.Select(v => v["name"].Value<string>())
.ToArray();
/*
subjectresults
{string[2]}
[0] [string]:"Science"
[1] [string]:"In library"
*/
The source json:
var json = #"{
""name"": {
""subjects"": [
{
""url"": ""https://openlibrary.org/subjects/science"",
""name"": ""Science""
},
{
""url"": ""https://openlibrary.org/subjects/in_library"",
""name"": ""In library""
}
]
}
}";

Linq query to Json string

starting from a JObject I can get the array that interests me:
JArray partial = (JArray)rssAlbumMetadata["tracks"]["items"];
First question: "partial" contains a lot of attributes I'm not interested on.
How can I get only what I need?
Second question: once succeeded in the first task I'll get a JArray of duplicated items. How can I get only the unique ones ?
The result should be something like
{
'composer': [
{
'id': '51523',
'name': 'Modest Mussorgsky'
},
{
'id': '228918',
'name': 'Sergey Prokofiev'
},
]
}
Let me start from something like:
[
{
"id": 32837732,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Of Thee I Sing: Overture (radio version)"
},
{
"id": 32837735,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : I. Allegro"
},
{
"id": 32837739,
"composer": {
"id": 245,
"name": "George Gershwin"
},
"title": "Concerto in F : II. Adagio"
}
]
First question:
How can I get only what I need?
There is no magic, you need to read the whole JSON string and then query the object to find what you are looking for. It is not possible to read part of the JSON if that is what you need. You have not provided an example of what the data looks like so not possible to specify how to query.
Second question which I guess is: How to de-duplicate contents of an array of object?
Again, I do not have full view of your objects but this example should be able to show you - using Linq as you requested:
var items = new []{new {id=1, name="ali"}, new {id=2, name="ostad"}, new {id=1, name="ali"}};
var dedup = items.GroupBy(x=> x.id).Select(y => y.First()).ToList();
Console.WriteLine(dedup);

Categories