Find field with specific key in Json - c#

In my c# project I use Json.net Library.
I have long Json with many subfields, for ex:
{
"count": 10,
"Foo1": [
{
"id": "1",
"name": "Name1"
},
{
"id": "2",
"name": "Name3"
},
{
"id": "3",
"name": "Name4"
}
],
"Foo2": [
{
"id": "4",
"name": "Name3",
"specific_field": "specific_values1"
},
{
"id": "5",
"name": "Name3",
"specific_field": "specific_values2"
},
{
"id": "6",
"name": "Name3",
"specific_field": "specific_values3"
}
],
"Foo3": [
{
"id": "7"
},
{
"id": "8"
},
{
"id": "9"
}
]
}
And I need to get List of all specific_field (id 4-6), but cant deserialized json to object, because Foo1, Foo2 ... changed dynamically.
I want to know, is this possible to get values of specific_field when i have only json?
I think, I found solution:
var list = new List<string>();
var result = ((JToken)json);
foreach (var res in result)
{
list.AddRange(from foo in res.First let ret = foo["specific_field"] where (dynamic) ret != null select foo["specific_field"].ToString());
}
In comment, provide, what do you think about it?

You could use dynamics:
string json = "your JSON string comes here";
dynamic deserializedValue = JsonConvert.DeserializeObject(json);
var values = deserializedValue["Foo2"];
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine(values[i]["specific_field"]);
}

Related

Add a field into JSON array C#

Here is my json Array, i want to add a new field in array but i dont know how to loop it
{
"data": {
"pasca": [
{
"code": "PDI1231",
"name": "Water Bottle",
"status": 1,
"price": 2500,
"type": "plastic"
},
{
"code": "PDI9999",
"name": "Soccel Ball",
"status": 1,
"price": 99123,
"type": "plastic"
}
]
}
}
i want to add a new field in pasca array like this
"pasca": [
{
"code": "PDI1231",
"name": "Water Bottle",
"status": 1,
"price": 2500,
"type": "plastic",
"new_field_1": "new value_1",
"new_field_2": "new value_2"
}
]
If you are using Newtosoft's Json.NET it can be done as simple as that:
var jObj = JsonConvert.DeserializeObject<JObject>(json);
foreach(var el in jObj["data"]["pasca"])
{
el["new_field_1"] = "new value_1";
}

How to compare single property from 2 array using c# execution time should be minimum

I have two arrays variables and values like below
arraydata1 =
[
{
"id": "1",
"name": "aaa"
},
{
"id": "2",
"name": "bbb"
},
{
"id": "3",
"name": "ccc"
},
{
"id": "4",
"name": "ddd"
},
{
"id": "12",
"name": "aaa"
}
]
and
arraydata2 =
[
{
"id": "111",
"tablename": "aaa"
},
{
"id": "222",
"tablename": "bbb"
}
]
I want to compare arraydata1.name == arraydata2.tablename and if matching then form new array from arraydata1 .
output is -
[
{
"id": "1",
"name": "aaa"
},
{
"id": "2",
"name": "bbb"
},
{
"id": "12",
"name": "aaa"
}
]
I have more than 2000+ records to compare in arraydata1 how to reduce time as well. I can use normal foreach but it will take too much time to compare.
I was doing inside logic app using 2 foreach so it is taking time. so i thought better to use c# code.
One Linq solution could look like this:
var tableNameKeys = arraydata2.Select(t => t.tablename).ToHashSet();
var resultArray = arraydata1.Where(x => tableNameKeys.Contains(x.name)).ToArray();
The advantage of this approach is that HashSet.Contains
... is an O(1) operation.
Result:

Dynamic creation of Json from C# Dataset with Parent/Child relation

I want to write a simple application that takes data from a database and formats it to a Json file. The catch is, that the views from which I'm getting the data are supposed to be changeable.
That means the Json can't be serialized from a rootclass. Also, I need to make sure if the tables have a parent/child connection this is depicted as well.
In the code below I have created a dataset to give you an idea of what I mean.
static void Main(string[] args)
{
DataSet dsSet = new DataSet("OrderManagement");
DataTable tCustumer = new DataTable("Custumer");
DataTable tOrder = new DataTable("Order");
tCustumer.Columns.Add("CustumerId");
tCustumer.Columns.Add("Name");
tOrder.Columns.Add("OrderId");
tOrder.Columns.Add("CustumerId");
tOrder.Columns.Add("Article");
tCustumer.Rows.Add("1", "Chris");
tCustumer.Rows.Add("2", "Ronja");
tCustumer.Rows.Add("3", "Thomas");
tOrder.Rows.Add("1", "1", "chocolate");
tOrder.Rows.Add("2", "1", "apples");
tOrder.Rows.Add("3", "2", "dogfood");
tOrder.Rows.Add("4", "3", "keyboard");
tOrder.Rows.Add("4", "3", "tomatos");
tOrder.Rows.Add("4", "3", "green tea");
dsSet.Tables.Add(tCustumer);
dsSet.Tables.Add(tOrder);
dsSet.Relations.Add(
"RelationCustumerOrder",
dsSet.Tables["Custumer"].Columns["CustumerId"],
dsSet.Tables["Order"].Columns["CustumerId"], false
);
dsSet.AcceptChanges();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.All;
string text = JsonConvert.SerializeObject(dsSet, Formatting.Indented, settings);
}
This is the Json I want it to output:
{"Custumer": [
{
"CustumerId": "1",
"Name": "Chris"
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
},
]
},
{
"CustumerId": "2",
"Name": "Ronja"
"Order": [
{
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
}
]
},
{
"CustumerId": "3",
"Name": "Thomas"
"Order": [
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}
]
}],}
This is what I do get:
{"Custumer": [
{
"CustumerId": "1",
"Name": "Chris"
},
{
"CustumerId": "2",
"Name": "Ronja"
},
{
"CustumerId": "3",
"Name": "Thomas"
}],
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
},
{
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}]}
You can do this in couple of steps.
Step 1 : Set Relation.Nested Property as True.
dsSet.Relations.Add(
"RelationCustumerOrder",
dsSet.Tables["Custumer"].Columns["CustumerId"],
dsSet.Tables["Order"].Columns["CustumerId"]
);
dsSet.Relations[0].Nested = true;
Step 2 : Convert to Xml.
StringWriter sw = new StringWriter();
dsSet.WriteXml(sw);
string xmlString = sw.ToString();
Step 3: Serialize as Json for final result
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.All;
string jsonResult = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
Final Output for the sample would be
{
"OrderManagement": {
"Custumer": [
{
"CustumerId": "1",
"Name": "Chris",
"Order": [
{
"OrderId": "1",
"CustumerId": "1",
"Article": "chocolate"
},
{
"OrderId": "2",
"CustumerId": "1",
"Article": "apples"
}
]
},
{
"CustumerId": "2",
"Name": "Ronja",
"Order": {
"OrderId": "3",
"CustumerId": "2",
"Article": "dogfood"
}
},
{
"CustumerId": "3",
"Name": "Thomas",
"Order": [
{
"OrderId": "4",
"CustumerId": "3",
"Article": "keyboard"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "tomatos"
},
{
"OrderId": "4",
"CustumerId": "3",
"Article": "green tea"
}
]
}
]
}
}

MongoDb: Rename a property in a complex document

We have documents saving to MongoDb. The problem is that one of our sub-documents has an Id property that is getting returned as _id, which is causing serialize/deserialize issues with the C# driver due to how it interprets Id fields (see http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/)
I would like to rename the property from Id to SetId, but our data is fairly dynamic and simple field rename solutions that I've seen elsewhere do not apply. Here's an example of some heavily edited simple data:
{
"Id": "5a6238dbccf20b38b0db6cf2",
"Title": "Simple Document",
"Layout": {
"Name": "Simple Document Layout",
"Tabs": [
{
"Name": "Tab1",
"Sections": [
{
"Name": "Tab1-Section1",
"Sets": [
{
"Id": 1
}
]
}
]
}
]
}
}
Compare with more complex data:
{
"Id": "5a6238dbccf20b38b0db6abc",
"Title": "Complex Document",
"Layout": {
"Name": "Complex Document Layout",
"Tabs": [
{
"Name": "Tab1",
"Sections": [
{
"Name": "Tab1-Section1",
"Sets": [
{
"Id": 1
}
]
},
{
"Name": "Tab1-Section2",
"Sets": [
{
"Id": 1
}
]
}
]
},
{
"Name": "Tab2",
"Sections": [
{
"Name": "Tab2-Section1",
"Sets": [
{
"Id": 1
}
]
}
]
},
{
"Name": "Tab3",
"Sections": [
{
"Name": "Tab3-Section1",
"Sets": [
{
"Id": 1
},
{
"Id": 2
}
]
}
]
}
]
}
}
Note that the Set.Id field can be on multiple tabs on multiple sections with multiple sets. I just don't know how to approach a query to handle renaming data at all these levels.
I took #Veerum's advice and did a manual iteration over the collection with something like this:
myCol = db.getCollection('myCol');
myCol.find({ "Layout.Tabs.Sections.Sets._id": {$exists: true} }).forEach(function(note) {
for(tab = 0; tab != note.Layout.Tabs.length; ++tab) {
for(section = 0; section != note.Layout.Tabs[tab].Sections.length; ++section) {
for(set = 0; set != note.Layout.Tabs[tab].Sections[section].Sets.length; ++set) {
note.Layout.Tabs[tab].Sections[section].Sets[set].SetId = NumberInt(note.Layout.Tabs[tab].Sections[section].Sets[set]._id);
delete note.Layout.Tabs[tab].Sections[section].Sets[set]._id
}
}
}
myCol.update({ _id: note._id }, note);
});
Perhaps there is a more efficient way, but we are still on Mongo v3.2 and it seems to work well.

Iterating through a nested JSON Array in C# with Newtonsoft

I have a block of JSON as follows:
[
{
"id": 1,
"name": "Section1",
"project_id": 100,
"configs": [
{
"id": 1000,
"name": "myItem1",
"group_id": 1
}
]
},
{
"id": 2,
"name": "Section2",
"project_id": 100,
"configs": [
{
"id": 1001,
"name": "myItem2",
"group_id": 2
},
{
"id": 1002,
"name": "myItem3",
"group_id": 2
},
{
"id": 1003,
"name": "myItem4",
"group_id": 2
}
]
},
{
"id": 3,
"name": "Section3",
"project_id": 100,
"configs": [
{
"id": 1004,
"name": "myItem5",
"group_id": 5
},
]
}
]
I have pulled it into Memory as a JArray.
I need to iterate through this such that I'm grabbing a list of ids and name from only the config sub-arrays. Ideally, I'll end up with something like this:
1000, myItem1
1001, myItem2
1002, myItem3
1003, myItem4
1004, myItem5
I'm having a hard time understanding what Newstonsoft calls a JObject vs a JArray, or how to access the various parts of each of those data structures. What I have right now is as follows:
foreach (JObject config in result["configs"])
{
string id = (string)config["id"];
string name = (string)config["name"];
string gid = (string)config["group_id"];
Console.WriteLine(name + " - " + id + " - " + gid);
}
This does not work, but I hope it illustrates what my end goal is. I've been unable to piece together how to accomplish this goal.
A JObject is an object (analogous to a class):
{
"a": 1,
"b": true
}
A JArray is a JSON array, and contains multiple JObject entities:
[
{
"a": 1,
"b": true
},
{
"a": 2,
"b": true
}
]
The root of a JSON document can be an object, or an array. In your case, it's an array.
The following code and fiddle reveals that your code is fine, provided that you deserialize the document as what it is - an array.
string json = "[{\"id\":1,\"name\":\"Section1\",\"project_id\":100,\"configs\":[{\"id\":1000,\"name\":\"myItem1\",\"group_id\":1}]},{\"id\":2,\"name\":\"Section2\",\"project_id\":100,\"configs\":[{\"id\":1001,\"name\":\"myItem2\",\"group_id\":2},{\"id\":1002,\"name\":\"myItem3\",\"group_id\":2},{\"id\":1003,\"name\":\"myItem4\",\"group_id\":2}]},{\"id\":3,\"name\":\"Section3\",\"project_id\":100,\"configs\":[{\"id\":1004,\"name\":\"myItem5\",\"group_id\":5},]}]";
JArray obj = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(json);
foreach (var result in obj)
{
foreach (JObject config in result["configs"])
{
string id = (string)config["id"];
string name = (string)config["name"];
string gid = (string)config["group_id"];
Console.WriteLine(name + " - " + id + " - " + gid);
}
}

Categories