c# can't build json hierarchy correctly using newtonsoft - c#

I looked at this SO question but it doesn't address my needs: Build JSON Hierarchy from Structured Data
The problem: When trying to build the json, the nesting of children isn't done correctly. The children property should contain 1 or more name array items like this:
"children": [{
"name": "XXX - Level XXX",
...instead it is generated as:
"children": []
Here's a dotnet fiddle with more code details:
I'm trying to build the tree by using json.net .Last to grab the last child and then add a JObject to that child but that isn't working out too well for me.
The main data structure used to build the json :
Dictionary<int, Industry>();
The desired json structure should be:
{
"name": "XX Level XX",
"children": [{
"name": "XXX - Level XXX",
"children": [{
"name": "XXXX - Level XXXX",
"children": [{
"name": "XXXXX - Level XXXXX",
"children": [{
"name": "XXXXXX - Level XXXXXX"
}]
}]
}]
}]
}
The actual output is:
{
"name": "XX-Level XX",
"children": [{
"name": "XXX-Level XXX",
"children": []
}, {
"name": "XXXX-Level XXXX",
"children": []
}, {
"name": "XXXXX-Level XXXXX",
"children": []
}, {
"name": "XXXXXX-Level XXXXXX",
"children": []
}
]
}
Here's the code that builds the json:
dynamic relationship = new JObject();
relationship.name = relationships[0].Industries[1].Name;
relationship.children = new JArray();
var lftIndustries = relationships[0].Industries.Where(k => k.Key > 1);
foreach (var item in lftIndustries)
{
//not good enough, need to get deepest, empty "children" node
// and add "industry" to it
var node = ((JContainer)relationship).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
}
json = relationship.ToString();
I thought that using json.net .Last and .Next would be the answer.

try this in your foreach loop and tell me if it is whats youre looking for:
JToken currentContainer = null;
foreach (var item in lftIndustries)
{
//not good enough, need to get deepest, empty "children" node
// and add "industry" to it
if (currentContainer != null)
{
var node = ((JContainer)currentContainer).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
currentContainer = industry;
}
else
{
var node = ((JContainer)relationship).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
currentContainer = industry;
}
}
The result is this:
{
"name": "XX-Level XX",
"children": [
{
"name": "XXX-Level XXX",
"children": [
{
"name": "XXXX-Level XXXX",
"children": [
{
"name": "XXXXX-Level XXXXX",
"children": [
{
"name": "XXXXXX-Level XXXXXX",
"children": []
}
]
}
]
}
]
}
]
}
Heres the fiddle: https://dotnetfiddle.net/1yzTGU

Related

Parsing Dynamic JSON in C#

I am working with an API that uses GraphQL and returns JSON data and I want to deserialize the JSON content dynamically rather than map the entire service structure in my application into C# data structures (.NET types/classes).
I've done this before but the JSON data was quite simple and straightforward. However, the this API I'm working with returns more complex/verbose JSON and I'm struggling to parse it properly.
Can anyone advise on how to parse the below JSON? That is, how to access the dynamic JSON's objects/properties.
I'm using Newtonsoft.Json. This is my code to deserialize:
byte bC = 0;
string location_text = string.Empty;
string location_value = string.Empty;
dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
foreach (dynamic d in results)
{
bC = d.data.locationSuggestions.Count; // d.locationSuggestions.Count
for (byte b = 0; b < bC; b++)
{
location_text = d.data.locationSuggestions[b].location.contextualName;
location_value = d.data.locationSuggestions[b].location.id.value;
}
}
When I run this code I get an error that says "data" or "locationSuggestions" cannot be found.
The JSON I'm trying to parse is as follows:
{
"data": {
"locationSuggestions": [
{
"location": {
"id": {
"value": "seekAnzPublicTest:location:seek:2dkY4vZJF"
},
"name": "Brisbane",
"contextualName": "Brisbane QLD 4000 AU",
"countryCode": "AU",
"parent": {
"id": {
"value": "seekAnzPublicTest:location:seek:2FjxhQans"
},
"name": "CBD & Inner Suburbs",
"parent": {
"id": {
"value": "seekAnzPublicTest:location:seek:32XZdsa2K"
},
"name": "Brisbane"
}
}
}
},
{
"location": {
"id": {
"value": "seekAnzPublicTest:location:seek:2ckmimaF1"
},
"name": "Brisbane Grove",
"contextualName": "Brisbane Grove NSW 2580 AU",
"countryCode": "AU",
"parent": {
"id": {
"value": "seekAnzPublicTest:location:seek:2UC23LszP"
},
"name": "Southern Highlands & Tablelands",
"parent": {
"id": {
"value": "seekAnzPublicTest:location:seek:FTwZdE2K"
},
"name": "New South Wales"
}
}
}
}
]
},
"extensions": {
"requestLatency": 171
}
}
Regarding your JSON string, you can use dynamic to parse it and access the data as shown below:
You can also find a working example at: https://dotnetfiddle.net/lnhwJz
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var jsonString=#"{'data':{'locationSuggestions':[{'location':{'id':{'value':'seekAnzPublicTest:location:seek:2dkY4vZJF'},'name':'Brisbane','contextualName':'Brisbane QLD 4000 AU','countryCode':'AU','parent':{'id':{'value':'seekAnzPublicTest:location:seek:2FjxhQans'},'name':'CBD & Inner Suburbs','parent':{'id':{'value':'seekAnzPublicTest:location:seek:32XZdsa2K'},'name':'Brisbane'}}}},{'location':{'id':{'value':'seekAnzPublicTest:location:seek:2ckmimaF1'},'name':'Brisbane Grove','contextualName':'Brisbane Grove NSW 2580 AU','countryCode':'AU','parent':{'id':{'value':'seekAnzPublicTest:location:seek:2UC23LszP'},'name':'Southern Highlands & Tablelands','parent':{'id':{'value':'seekAnzPublicTest:location:seek:FTwZdE2K'},'name':'New South Wales'}}}}]},'extensions':{'requestLatency':171}}";
var parsedData=JsonConvert.DeserializeObject<dynamic>(jsonString);
foreach(var item in parsedData.data.locationSuggestions)
{
Console.WriteLine(item.location.name);
Console.WriteLine(item.location.id.value);
Console.WriteLine(item.location.contextualName);
}
}
}
Output:
Brisbane
seekAnzPublicTest:location:seek:2dkY4vZJF
Brisbane QLD 4000 AU
Brisbane Grove
seekAnzPublicTest:location:seek:2ckmimaF1
Brisbane Grove NSW 2580 AU

How to upload/index a GeoJson file in Elasticsearch using NEST(C#)

I have GeoJson File with me which i want to index on Elastic Search through NEST
But Due to lack of expertise I am having trouble in indexing the document
I have created a class which represent the Mapping on ElasticSearch:
public class GeoDocument
{
[Nest.Keyword(Name = "DocId")]
public string DocId { get; set; }
[Nest.GeoShape(Name = "GeoField")]
public object GeoField { get; set; }
}
But when i use this Mapping to index a Document
var polygon = "{\"type\":\"Polygon\",\"coordinates\":[[[5.856956,51.002753],[5.856928,51.002771],[5.856687,51.002853],[5.856956,51.002753]]]}";
var geoDocument = new GeoJson
{
DocId = "1",
GeoField = JsonConvert.DeserializeObject<object>(polygon)
};
var IndexResponse = client.IndexDocument(geoDocument);
I get a Result Something like This
"_source": {
"DocId": "1",
"GeoField": [
[
[]
],
[
[
[
[
[],
[]
],
[
[],
[]
],
[
[],
[]
],
[
[],
[]
]
]
]
]
]
}
}
In order to make that JObject saved correctly, you have to tell the ElasticClient to use NewtonSoft .Net serializer.
Install NEST.JsonNetSerializer package
Reference the JsonNetSerializer in your ConnectionSettings
If you get 400 after changing the settings, you might need to create a new Index.
Sample code
using Nest;
using Elasticsearch.Net;
using Nest.JsonNetSerializer;
SingleNodeConnectionPool node = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
ConnectionSettings settings = new ConnectionSettings(
node,
JsonNetSerializer.Default
);
settings.DefaultMappingFor<GeoDocument>(m => m.IndexName("project2"));
ElasticClient client = new ElasticClient(settings);
// This is Supposed to be GeoDocument as per your question.
GeoDocument geoDocument = new GeoDocument
{
DocId = "1",
GeoField = JObject.Parse(polygon)
// GeoField = JsonConvert.DeserializeObject<object>(polygon) // <-- Works too.
};
IndexResponse IndexResponse = client.IndexDocument(geoDocument);
Response
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "project2",
"_type": "_doc",
"_id": "COQRXW8BNG2RJmIOyoO0",
"_score": 1.0,
"_source": {
"DocId": "1",
"GeoField": {
"type": "Polygon",
"coordinates": [
[
[
5.856956,
51.002753
],
[
5.856928,
51.002771
],
[
5.856687,
51.002853
],
[
5.856956,
51.002753
]
]
]
}
}
}
]
}
}

how to post array json .net?

i am inserting json format but need to know how i can insert in this format as mention below
{
"products": [
{
"product_id": "55",
"name": "testing data",
"price": "77",
"total": "77",
"quantity": "1",
"type": "kg"
}],
],
"totals": [
{
"code": "sub_total",
"title": "Sub-Total",
"text": "Rs277.00",
"value": "277.0000",
"sort_order": "1"
}]
}
here is my code which i am trying
items local = new items();
foreach (var item in _LocalItem){
local = new items
{
name = item.name
};
}
var json = JsonConvert.SerializeObject(local);
var request = new HttpRequestMessage(HttpMethod.Post, "http://orangepotato.rjcpacking.com/index.php?route=api/login/addcustomerOrder");
request.Content = new StringContent(json);
i dont understand where i can add "products" array in json format
Simply: don't serialize an array - serialize something that has an array in a member called products:
var json = JsonConvert.SerializeObject(new { products = local });

json object data accessing via index

I have following json object of array structure.I am trying to retrieve certain elements from array of objects
{
"data": [
{
"_id": "5b62dc6ebef986403db8aafd",
"name": "smitha vijaya",
"designation": "account management",
"projects": {
"project1": "description1",
"project2": "description2"
},
"age": "27"
},
{
"_id": "5b62dd17bef986403db8ab90",
"name": "JIKKU VARGHESE",
"designation": "SUPERVISING OPERATIONS MANAGER",
"projects": {
"project1": "description1",
"project2": "description2"
},
"age": "27"
},
{
"_id": "5b62dd76bef986403db8abe3",
"name": "SUJEETH NAIR",
"designation": "MENA AMS",
"projects": {
"project1": "description1",
"project2": "description2"
},
"age": "30"
},
{
"_id": "5b62ddb1bef986403db8ac13",
"name": "GIRISH KN",
"designation": "MENA AMS",
"projects": {
"project1": "description1",
"project2": "description2"
},
"age": "27"
}
]
}
I am using following c# code to extract ist name (smitha)
JsonData jsonvale = JsonMapper.ToObject( jsonString);
Name = jsonvale["data"][0]["name"].ToString();
print (name);
how can i acces other elements like name jikku and so on?
You could iterate using a for loop:
for(int i = 0; i < jsonvale.length; i++) {
JsonData jsonvale = JsonMapper.ToObject(jsonString);
Name = jsonvale["data"][i]["name"].ToString();
print(name);
}
You can iterate it over your json array like following:
JsonData jsonvale = JsonMapper.ToObject( jsonString);
for (var i=0; i<jsonvale.length; i++){
print(jsonvale["data"][i]["name"].ToString());
}
Just deserialize this json in List() and then you can access all data from this list without loops, and when you do not need this list anymore, you can destroy it. See this example https://github.com/IonCojucovschi/JsonDeserializeGenericForm

Transform nested JSON arrays into an array of JSON objects

I have the following set of variable JSON data where the first row is the list of element names and the other rows represent the list of element values:
[
[
"category",
"author",
"title",
"price"
],
[
"reference",
"Nigel Rees",
"Sayings of the Century",
"8.95"
],
[
"fiction",
"Evelyn Waugh",
"Sword of Honour",
"12.99"
],
[
"fiction",
"Herman Melville",
"Moby Dick",
"8.99"
],
[
"fiction",
"J. R. R. Tolkien",
"The Lord of the Rings",
"22.99"
]
]
I want to build the following type of JSON object from the data:
{
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
]
}
How can I build my JSON object which should be identical to the above. I don't see any direct support for doing this using JSON.NET APIs.
Any help is greatly appreciated.
This is just an idea to get you on the right track.
JObject obj = new JObject();
var child = new JArray();
var child2 = new JObject();
child2.Add("category", "references");
child.Add(child2);
obj.Add("book", child);
var result = obj.ToString();
I won't do the string parsing for you, i think you should be able to handle that.
The piece of code I've given produces the following JSON:
{
"book": [
{
"category": "references"
}
]
}
Hope this helps.
You can do this transformation using Json.Net's LINQ-to-JSON API:
JArray array = JArray.Parse(origJson);
string[] keys = array.First().Select(t => t.ToString()).ToArray();
JArray array2 =
new JArray(array.Skip(1).Select(a =>
new JObject(a.Select((t, i) =>
new JProperty(keys[i], t)
))
));
JObject obj = new JObject(new JProperty("book", array2));
string finalJson = obj.ToString();
Fiddle: https://dotnetfiddle.net/kMyHOe

Categories

Resources