count Jarray in C# - c#

I need to count data from reqst body in httptrigger function.Data is coming as object type.
I am deserialisizing the reqd body as shown below.Below are the object type data i am getting in req.body.
{
"Response": [
{
"id": "1",
"name": "Warburtons Medium Sliced Soft White Bread 400g",
"description": "Warburtons Medium Sliced White 400G",
"brand": "Warburtons",
"ean": "123",
"mediaStorageKey": "b",
"maxQuantity": 6,
"price": 0.95,
"size": 400,
"sizeUnits": "Grams"
},
{
"id": "a",
"name": "Co-op Orvieto Classico 75cl",
"description": "Co-op Orvieto Classico 75CL",
"brand": "Co-op",
"ean": "489",
"mediaStorageKey": "c",
"maxQuantity": 6,
"price": 5.5,
"size": 75,
"sizeUnits": "Centilitres"
},
{
"id": "kl",
"name": "Co Op Garden Peas in Water 290g",
"description": "Co-op Garden Peas 290G",
"brand": "Co Op",
"ean": "678",
"mediaStorageKey": "f",
"maxQuantity": 6,
"price": 0.45,
"size": 175,
"sizeUnits": "Grams"
}
]
}
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic body = JsonConvert.DeserializeObject(requestBody);
dynamic data = body["Response"];
Till this i am getting data like below.
{[{"id":"1","name":"b"},{"id":"f","name":"j"}]}
But now i am not able to count these data which gives 2 in this case as i have to apply for loop. Neither Count,Count() is working here. I am getting the below error.
Newtonsoft.Json.Linq.JValue does not contain a definition for Count

create a class with these two fields id and name
public class Item {
public Int Id {get; set;}
public String Name {get; set;}
}
and specify the type for your deserialized value:
dynamic body = JsonConvert.DeserializeObject(requestBody);
var rows = JsonConvert.DeserializeObject<List<Item>>(body["Response"]);
now you can use rows.Count();

If you only need to know the amount of entries inside the Response collection then you can simply do that by making use of JObject and JArray:
string rawJson = ...;
JObject semiParsedJson = JObject.Parse(rawJson);
JArray entries = (JArray)semiParsedJson["Response"];
int count = entries.Count;

Related

How do I take a JSON string and select a random entry and get the variables from that entry

I have the following json..
{
"Followers": [{
"ID": 0,
"Username": "nutty",
"Game": "Just Chatting",
"Viewers": 200,
"Image": "https://static-cdn.jtvnw.net/previews-ttv/live_user_nutty-1920x1080.jpg"
}, {
"ID": 1,
"Username": "CloneKorp",
"Game": "Software and Game Development",
"Viewers": 31,
"Image": "https://static-cdn.jtvnw.net/previews-ttv/live_user_clonekorp-1920x1080.jpg"
}, {
"ID": 2,
"Username": "kingswarrior9953",
"Game": "Art",
"Viewers": 1,
"Image": "https://static-cdn.jtvnw.net/previews-ttv/live_user_kingswarrior9953-1920x1080.jpg"
}]
}
I'd like to do something like..
JObject data = JObject.Parse(json);
int SelectedViewers = data["Followers"][1]["Viewers"];
Where it would grab the second entry (the ID of 1 entry) and set the variable of "Viewers" to 31. The number would be a random number based on the count of all the entries, but I'm not to that point yet.
However, this doesn't seem to work. Any ideas on what is broken here?
You are missing casting here:
int SelectedViewers = Int32.Parse((string)data["Followers"][1]["Viewers"]);
The above should work.
try this
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var followers = (JArray)JObject.Parse(json)["Followers"];
var id=1;
int selectedViewers = followers.Where(f=> (int)f["ID"]==id)
.Select(f => (int) f["Viewers"])
.FirstOrDefault(); //31

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);

Printing out the first index of an array in JSON format

What I am trying to do is print out the first index of an array in JSON format.
With the code:
storeInformation = myStoreInfoTable;
strResponseOutput = JsonConvert.SerializeObject(storeInformation);
These are the results:
[
{
"distance": 0,
"descr": "Toronto",
"address": "1300 Castlefield Avenue",
"city": "Toronto"
},
{
"distance": 7.1121883392,
"descr": "Etobicoke - North",
"address": "Resources Road",
"city": "Etobicoke"
}
]
What I tried to do to get the first index is:
storeInformationRow = dtbStoreInformation.Rows[0];
strResponseOutput = JsonConvert.SerializeObject(storeInformationRow);
What I get is:
{
"RowError": "",
"RowState": 2,
"Table": [
{
"distance": 0.0000000000,
"descr": "Toronto",
"address": "1300 Castlefield Avenue",
"city": "Toronto"
},
{
"distance": 7.1121883392,
"descr": "Etobicoke - North",
"address": "Resources Road",
"city": "Etobicoke"
}
]
}
The result I want is just
{
"distance": 0.0000000000,
"descr": "Toronto",
"address": "1300 Castlefield Avenue",
"city": "Toronto"
}
Help anybody?
I seems to me that the JSON serializer is goofing up because it doesn't know how to correctly serialize a DataRow. That's the only difference between the first and second snippet of code.
If you look at the MSDN documentation for the DataRow class you can see that the DataRow has the attributes displayed (RowError, RowState and Table) among many others.
To fix your problem I would suggest one of 2 options:
Create a new DataTable and add the DataRow you want to serialize to it, and call JsonConvert.SerializeObject() on that.
Map the columns (distance, descr, address & city) to another class (Store or something) and try to serialize that object. From what I read in the JsonConvert documentation it's possible (the class attributes are mapped correctly onto the JSON object).
Let me know how it goes!
you can just use :
var row = dtbStoreInformation.Rows[0];
string strResponseOutput = new {
distance = row[0].ToString(),
descr= row[1].ToString(),
address = row[2].ToString(),
city = row[2].ToString()}.ToJson();
don't forget the include of the namespace ServiceStack.Text
You can also create an anonym object
var obj = jsonString = new {
distance = row[0].ToString(),
descr= row[1].ToString(),
address = row[2].ToString(),
city = row[2].ToString()}
strResponseOutput = JsonConvert.SerializeObject(obj);

JSON C# Parsing Error

This is my JSON
{
"3659639": {
"EventID": 3659639,
"RaceNum": 2,
"Meeting": "Newton Abbot",
"RaceType": "T",
"Description": "Attheraces.Com Handicap Chase",
"Distance": "5300m",
"TrackCondition": "Good",
"Weather": "Overcast",
"Abandoned": 0,
"SuspendDateTime": "2014-06-17 00:00:42.0000000",
"OutcomeDateTime": "2014-06-17 00:00:00.0000000",
"EffectiveRaceDate": "2014-06-16",
"Status": "Paying",
"Results": [
{
"event_id": 3659639,
"saddle_number": 11,
"position": 1,
"status": "Final"
},
{
"event_id": 3659639,
"saddle_number": 16,
"position": 2,
"status": "Final"
},
{
"event_id": 3659639,
"saddle_number": 17,
"position": 3,
"status": "Final"
}
],
"Dividends": {
"0": {
"event_id": 3659639,
"source": "NSW",
"pool_type": "Duet",
"outcome": "11\/16",
"pool_value": 79.5,
"interim_dividend": 11.2,
"final_dividend": 11.2
},
"36": {
"event_id": 3659639,
"source": "VIC",
"pool_type": "Trifecta",
"outcome": "11\/16\/17",
"pool_value": 1733,
"interim_dividend": 2746.2,
"final_dividend": 2746.2
},
"37": {
"event_id": 3659639,
"source": "VIC",
"pool_type": "Win",
"outcome": "11",
"pool_value": 2541.06,
"interim_dividend": 25.5,
"final_dividend": 25.5
},
"RunnerProducts": {
"11": {
"TopeTotePlace": 12,
"MidTotePlace": 7.3,
"TopeToteWin": 29.8,
"MidToteWin": 28,
"BestOrSP": 29.8
},
"16": {
"TopeTotePlace": 2.3,
"MidTotePlace": 2
},
"17": {
"TopeTotePlace": 26.4,
"MidTotePlace": 24.2
}
}
}
},
"3622800": {
"EventID": 3622800,
"RaceNum": 2,
"Meeting": "Albion Park",
"RaceType": "H",
"Description": "Seymour Rising Stars Championship C0 Heat One",
"Distance": "1660m",
"TrackCondition": "Good",
"Weather": "Fine",
"Abandoned": 0,
"SuspendDateTime": "2014-06-17 15:09:10.0000000",
"OutcomeDateTime": "2014-06-17 15:08:00.0000000",
"EffectiveRaceDate": "2014-06-17",
"Status": "Closed",
"Results": [
],
"Dividends": {
"RunnerProducts": [
]
}
},
"3679673": {
"EventID": 3679673,
"RaceNum": 6,
"Meeting": "Thirsk",
"RaceType": "T",
"Description": "Market Cross Jewellers Handicap",
"Distance": "1200m",
"TrackCondition": null,
"Weather": null,
"Abandoned": 0,
"SuspendDateTime": "2014-06-18 02:20:00.0000000",
"OutcomeDateTime": "2014-06-18 02:20:00.0000000",
"EffectiveRaceDate": "2014-06-17",
"Status": "Open",
"Results": [
],
"Dividends": {
"RunnerProducts": [
]
}
}
}
I am trying to parse this using JSON.Net and i have tried this code.
var obj = JObject.Parse(json);
var query =
from JProperty ev in obj.AsJEnumerable()
from JProperty evid in ev.Value.AsJEnumerable()
let value = (JObject)evid.Value
select new
{
Description = (string)value["Description"]
};
I am getting this error "Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'."
i also want to read event_id which is inside results and dividents. Can anyone tell me what i am doing wrong here
Currently, you're getting the properties of the properties - and then trying to cast each of the values to JObject, and then taking the Description of that. That's one level too deep, as you have:
The root object
Each property of the root object, which genuinely has an object as its value
Each property of each of those values... most of which are just string properties, so the value can't be cast to JObject
It's not clear why you're using AsJEnumerable() at all, but all you need is the properties of the root object, which is easily obtained with the Properties() method. Likewise it's not clear why you're using an anonymous type, rather than just getting a sequence of strings. This works fine:
var query =
from ev in obj.Properties()
select (string) ev.Value["Description"];
Or without the query syntax:
var query = obj.Properties.Select(ev => (string) ev.Value["Description"]);
Next:
i also want to read event_id which is inside results and dividents
In the data you've given, that's always the same as the value of the EventID property in the top-level type. So you'd be better off with:
var query =
from ev in obj.Properties()
select new { Description = (string) ev.Value["Description"],
Id = (string) ev.Value["EventID"] };
If you really want to get at the values in the dividends and results, you'll need to work out how you'll handle the multiple entries in those properties.

C# Linq Convert Object Property to Array

I have an object that I am converting to JSON to be consumed by Ember.js.
Currently I have some child objects that are fully expanded but ember expects
just an array of ids on the client side. How can I flatten the object out to
be a int[]
items = Mapper.Map<IList<Item>>(client.GetItems());
foreach (var item in items)
{
int[] choices = item.Choices.Select(x => x.Id).ToArray();
item.Choices = choices;
}
get an error about not being able to convert to type int[] from IList<Item>
how can I cast the property?
example current JSON I produce after serializing
{ "items": [
{
"id": 0,
"name": "Item0",
"description": "...",
"choices": [
{ "id": 0, "property": "somevalue" },
{ "id": 1, "property": "somevalue" },
]
},
{
"id": 1,
"name": "Item1",
"description": "...",
"choices": [
{ "id": 0, "property": "somevalue" },
{ "id": 1, "property": "somevalue" },
]
}
]}
The JSON I would like to produce
{ "items": [
{
"id": 0,
"name": "Item0",
"description": "...",
"choices": [0, 1]
},
{
"id": 1,
"name": "Item1",
"description": "...",
"choices": [0, 1]
}
]}
SelectMany flattens List of Lists and produces single List with all items.
items.SelectMany(x=>x.Choices.Select(y=>y.Id).ToArray()));
get an error about not being able to convert to type int[] from IList how can I cast the property?
You cannot cast one type to another. Instead you can create another property of type int[] in your class and use the LINQ statement in getter (with necessary validation checks).
public int[] ChoiceIDs
{
get {
return this.Choices.Select(x => x.Id).ToArray();
}
}

Categories