Combine 2 json using a key - c#

Suppose i have
Json1:
[
{
"key":"1",
"val2":"5",
"val3":"short",
"val4":"pant",
"val5":"blue",
},
{
"key":"2",
"val2":"6",
"val3":"long",
"val4":"shirt",
"val5":"red",
}
]
And I have Json2:
[
{
"key":"1",
"qty":"3"
},
{
"key":"2",
"qty":"6",
}
]
I would like to have the following results
Json3:
[
{
"key":"1",
"val2":"5",
"val3":"short",
"val4":"pant",
"val5":"blue",
"qty":"3"
},
{
"key":"2",
"val2":"6",
"val3":"long",
"val4":"shirt",
"val5":"red",
"qty":"6"
}
]
is there a way to combine using a key in my case I would want to use the "key" as the key to know what qty to place where.
I'm trying to achieve a similar effect of an inner join to combine them that way.
Thanks,

var json1 = '[' +
'{ "key":"1" , "val2":"5", "val3":"short", "val4":"pant","val5":"blue" }, ' +
'{ "key":"2", "val2":"6", "val4":"shirt", "val5":"red" } ]';
var json2 = '[' +
'{ "key":"1", "qty":"3"}, ' +
'{ "key":"2", "qty":"6" } ]';
var obj1 = JSON.parse(json1);
var obj2 = JSON.parse(json2);
for(var i in obj1) {
if(obj1[i].key === obj2[i].key) {
obj1[i].qty = obj2[i].qty;
}
}
console.log(obj1);

Using Json.net's merge method:
var json1 = JArray.Parse(#"[
{
""key"":""1"",
""val2"":""5"",
""val3"":""short"",
""val4"":""pant"",
""val5"":""blue"",
},
{
""key"":""2"",
""val2"":""6"",
""val3"":""long"",
""val4"":""shirt"",
""val5"":""red"",
}
]");
var json2 = JArray.Parse(#"[
{
""key"":""1"",
""qty"":""3""
},
{
""key"":""2"",
""qty"":""6"",
}
]");
json1.Merge(json2, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Merge
});

Related

How to search and get only sub document using C# mongoDB

I have data in provinces collection like this:
{
"_id": {
"$oid": "63dc7ff82e7e5e91c0f1cd87"
},
"province": "province1",
"districts": [
{
"district": "district1",
"sub_districts": [
{
"sub_district": "sub_district1",
"zip_codes": [
"zip_code1"
]
},
{
"sub_district": "sub_district2",
"zip_codes": [
"zip_code2"
]
},
],
},
],
}
This is how I get a list of sub_district for now:
- I search for province using Builders.Filter.
- Use foreach to get districts array (In province collection) and use if-statement to check if district equal searchDistrict.
- Get sub_districts array in that distric.
Source code:
public static List<string> MongoDbSelectSubDistrict(string searchProvince, string searchDistrict)
{
List<string> subDistrictList = new List<string>();
try
{
var provincesCollection = _db.GetCollection<BsonDocument>("provinces");
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Empty;
if (searchProvince != "")
{
var provinceFilter = Builders<BsonDocument>.Filter.Eq("province", searchProvince);
filter &= provinceFilter;
}
/*
//***Need to be revised***
if (searchDistrict != "")
{
var districtFilter = Builders<BsonDocument>.Filter.Eq("provinces.district", searchDistrict);
filter &= districtFilter;
}
*/
var queryProvinces = provincesCollection.Find(filter).ToList();
foreach (BsonDocument queryProvince in queryProvinces)
{
BsonArray districtArray = queryProvince.GetValue("districts").AsBsonArray;
foreach (BsonDocument districtDocument in districtArray)
{
string district = districtDocument.GetValue("district").ToString();
if (district == searchDistrict) //***Need to be revised***
{
BsonArray subDistrictArray = districtDocument.GetValue("sub_districts").AsBsonArray;
foreach (BsonDocument subDistrictDocument in subDistrictArray)
{
string subDistrict = subDistrictDocument.GetValue("sub_district").ToString();
subDistrictList.Add(subDistrict);
}
}
}
}
}
catch (TimeoutException ex)
{
}
return subDistrictList;
}
Is there any efficient way to get this?
This is what I want:
[
{
"sub_district": "sub_district1",
"zip_codes": [
"zip_code1"
]
},
{
"sub_district": "sub_district2",
"zip_codes": [
"zip_code2"
]
},
]
And one more question: if I want to search for sub_district in the collection, how do I get this without looping in sub_districts array?

merging two json result into one and adding the Key inside array?

I've merged two JSON response into a single object:
This is how I did it
string peter= "\"peter\"";
string james= "\"james\"";
var jsonStringJames = await jsonStringJames .Content.ReadAsStringAsync();
var jsonStringPeter = await responsePeter.Content.ReadAsStringAsync();
return Ok("{" + peter+ ":" + jsonStringPeter + ","+ james+ ":" + jsonStringJames + "}");
my JSON looks as follow:
{
"peter": {
"total": 1,
"result": [
{
"value": "James Bond",
"OWNER":"peter" <--- add this
}
]
},
"james": {
"count": 2,
"next": null,
"previous": null,
"results": [{
"gender": "male"
"OWNER":"james" <--- add this
}]
}
}
How do I add the object name as a key? server-side?
Thanks alot!
try this using ´JObject´
var jsonStringPeter = await responsePeter.Content.ReadAsStringAsync();
var objJson = JObject.Parse(jsonStringPeter);
objJson["result"][0]["OWNER"] = "peter";
var jsonStringJames = await jsonStringJames.Content.ReadAsStringAsync();
var objJson2 = JObject.Parse(jsonStringJames);
objJson2["OWNER"] = "james";

JSON - LINQ Query for object or an array to group two data with same key value pair

Consider I have a JSON data as:
{
"entities":[
{
"republish": false,
"OrgID": "",
"createdby": "730",
"questions": [
{
"sequence": "5",
"QuestionId": "57BB6DDC-A90A-10EE-E224-EC658A825871",
"metadata": [
{
"key": "Group",
"value": 0
},
{
"key": "Part",
"value": "0"
}
]
},
{
"sequence": "4",
"QuestionId": "57BB6DDC-A90A-10EE-E224-EC658A825871",
"metadata": [
{
"key": "Group",
"value": 1
},
{
"key": "Part",
"value": "A"
}
]
},
{
"sequence": "3",
"QuestionId": "57BB6DDC-A90A-10EE-E224-EC658A825871",
"metadata": [
{
"key": "Group",
"value": 1
},
{
"key": "Part",
"value": "B"
}
]
}
]
}
]
}
As you can see I have a list of questions available and in each question, I have a metadata which holds Key-Value pair.
Above example demonstrates, I have 3 questions and out of it 2 question, metadata key-value is "Group 1".
Now I want to do is combine the questions with a same key-value pair and treat it as one.
so in my final case, I will have 2 questions instead of 3. And out of that one question will have two separate questions inside.
And I want to achieve this using Linq query. And if possible please use Newtonsoft for parse if needed. I have been stuck for long onto this.
Things I have done:
public virtual HttpResponseMessage AddQuestionsToStandardMaster(TaxonomyMetaData objQuestion)
{
List<ResponseEntity> objResponseList = new List<ResponseEntity>();
try
{
if (ModelState.IsValid)
{
foreach (var objEntity in objQuestion.Entities)
{
EntityResponse objentityresponse = new EntityResponse();
ResponseEntity objResponse = new ResponseEntity();
}
List<Question> objQuestionList = new List<Question>();
if (objEntity.Questions.Length > 0)
{
foreach (var item in objEntity.Questions)
{
int questionTypeid = 0;
dynamic objQuestionJson = JObject.Parse(item.ToString())
}
}
}
Question objCurrentQuestion = new Question();
Question objQuestionforDelete = new Question();
JObject itemToParese = new JObject();
string SingleQuestionJson = objQuestionJson.GetValue("QuestionData").ToString();
string questionstem = "";
Regex rgx = new Regex("/\'");
objCurrentQuestion.Sequence = Convert.ToInt32(objQuestionJson.GetValue("sequence"));
objCurrentQuestion.tag = objQuestionJson.tag.ToObject<JToken[]>(); ;
objCurrentQuestion.metadata = objQuestionJson.metadata.ToObject<JToken[]>();
objCurrentQuestion.SingleQuestionJson = rgx.Replace(SingleQuestionJson, "'");
objCurrentQuestion.QuestionsType = questionTypeid;
objCurrentQuestion.QuestionsId = new Guid(objQuestionJson.GetValue("QuestionId").ToString());
objCurrentQuestion.VersionNo = Convert.ToInt32(objQuestionJson.GetValue("VersionNo"));
objCurrentQuestion.DisplayQuestionId = Convert.ToString(objQuestionJson.GetValue("DisplayQuestionId"));
objCurrentQuestion.OriginalQuestionId = Convert.ToString(objQuestionJson.GetValue("OriginalQuestionId"));
objCurrentQuestion.PassageText = Convert.ToString(objQuestionJson.GetValue("passage_text"));
objCurrentQuestion.PassageCode = Convert.ToString(objQuestionJson.GetValue("passage_id"));
objCurrentQuestion.PassageTitle = Convert.ToString(objQuestionJson.GetValue("passage_title"));
objCurrentQuestion.IsPublished = Convert.ToByte(true);
objCurrentQuestion.ProductId = objEntity.ProductID;
foreach (var metadata in objCurrentQuestion.metadata)
{
switch (metadata["key"].ToString())
{
case "Group":
objCurrentQuestion.Group = Convert.ToInt32(metadata["value"].ToString());
break;
case "Part":
objCurrentQuestion.Part = metadata["value"].ToString();
break;
}
}
objQuestionList.Add(objCurrentQuestion);
int counter = 1;
//Here I get the data in a group which needs to coverted to JSOn and then replace the original JSON data with this. But I know this is irrelevant to what we need to achieve.
var yui = objQuestionList.Where(tma => tma.Group == counter).Select(t => t).GroupBy(s => new { s.Group }).Where(p => p.Count() > 1).ToList();
//After proper conversion I need to enter this data to a database.
I am a bit unclear on what do you mean by make it
combine the questions with a same key-value pair and treat it as one
But here is how you can group by the JSON into groups in metadata you can do a custom select to what ever you want.
var text = #"{
""entities"":[
{
""republish"": false,
""OrgID"": """",
""createdby"": ""730"",
""questions"": [
{
""sequence"": ""5"",
""QuestionId"": ""57BB6DDC-A90A-10EE-E224-EC658A825871"",
""metadata"": [
{
""key"": ""Group"",
""value"": 0
},
{
""key"": ""Part"",
""value"": ""0""
}
]
},
{
""sequence"": ""4"",
""QuestionId"": ""57BB6DDC-A90A-10EE-E224-EC658A825871"",
""metadata"": [
{
""key"": ""Group"",
""value"": 1
},
{
""key"": ""Part"",
""value"": ""A""
}
]
},
{
""sequence"": ""3"",
""QuestionId"": ""57BB6DDC-A90A-10EE-E224-EC658A825871"",
""metadata"": [
{
""key"": ""Group"",
""value"": 1
},
{
""key"": ""Part"",
""value"": ""B""
}
]
}
]
}
]
}";
var json = JObject.Parse(text);
var groupedData = from entity in json["entities"]
from question in entity["questions"]
group question by question["metadata"][0]["value"] into questionGroup
select questionGroup;
foreach (var data in groupedData)
{
Console.WriteLine("_____________________");
Console.WriteLine("Group");
Console.WriteLine(data.Key);
foreach (var question in data)
{
Console.WriteLine(question["QuestionId"]);
}
Console.WriteLine("_____________________");
}
If "Group" is not always the fist item in the array you can do
question["metadata"].First(md => md.Value<string>("key") == "Group")["value"]
to get it.

Read json without knowing the key in c#

I want to parse the below mentioned JSON and get all values of screenshot.thumbnailUrl. But below are my constraints:
Not all nodes have screenshot. In this example only "weather" and "entities" have it.
I do not know the node names. In this example I didn't know that there would be a node named "weather" or "entities". These nodes are auto generated based on the query i made to get the json.
There are two possible places where screenshot can be present. (1) In the child of rootobject e.g. weather.screenshot (2) In all values of child of rootobject e.g. entities.value[0].screenshot, entities.value[1].screenshot etc.
{ "_type": "SearchResponse", "queryContext": {}, "webPages": {}, "entities": {
"queryScenario": "DominantEntity",
"value": [
{
"_type": "Place",
"id": "https://www.someapi.com/api/v6/#Entities.0",
"screenshot": {
"thumbnailUrl": "http://Screenshot_URL_I_Want",
"width": 285
},
"name": "Seattle",
"entityPresentationInfo": {},
"bingId": "5fbba6b8-85e1-4d41-9444-d9055436e473",
"boundingBox": [],
"weather": {},
"timeZone": "Pacific Standard Time"
}
] }, "images": {}, "weather": {
"id": "https://www.someapi.com/api/v6/#Weather",
"screenshot": {
"thumbnailUrl": "http://Screenshot_URL_I_Want",
"width": 285
},
"location": {},
"currentWeather": {},
"dailyForecast": [] }, "rankingResponse": {} }
This is what worked for me... I am looking for a cleaner solution though...
static async void getJobject(string jsonstring)
{
JObject response = await JObject.Parse(jsonstring);
foreach (var node in response.Children())
{
Console.WriteLine(node.Path);
string propertyPath = node.Path + ".screenshot.thumbnailUrl";
var token = response.SelectToken(propertyPath);
if (token != null)
{
Console.WriteLine("Check this=> " + token.ToString()); //Prints screenshot URL from weather
}
else
{
propertyPath = node.Path + ".value";
token = response.SelectToken(propertyPath);
if (token != null)
{
int count = token.Children().Count();
for (int i = 0; i < count; i++)
{
propertyPath = node.Path + ".value" + "[" + i.ToString() + "]" + ".screenshot.thumbnailUrl";
var mytoken = response.SelectToken(propertyPath);
if (mytoken != null)
{
Console.WriteLine("Check this=> " + mytoken.ToString()); //Prints screenshot URL from entities
}
}
}
}
}
}
You could use code like this to parse the JSon and recursively iterate through it. You will have to probably refine the logic in the lambda of the call to RecursiveDescent to make it correct and robust for your type of JSON:
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string json = #"....your JSON ....";
var node = JToken.Parse(json);
RecursiveDescent(node, n =>
{
JToken url = n["thumbnailUrl"];
if (url != null && url.Type == JTokenType.String)
{
var nodeWeWant = url?.Parent?.Parent?.Parent?.Parent;
Console.WriteLine(nodeWeWant.ToString());
}
});
}
static void RecursiveDescent(JToken node, Action<JObject> action)
{
if (node.Type == JTokenType.Object)
{
action((JObject)node);
foreach (JProperty child in node.Children<JProperty>())
RecursiveDescent(child.Value, action);
}
else if (node.Type == JTokenType.Array)
{
foreach (JToken child in node.Children())
RecursiveDescent(child, action);
}
}
}
}

Datatables.Net - not populating from JSON data

I am working with a Datatables.Net plug into an internal web application to my company.
The issue Im facing is in the variable JSON, I can see that I have returned a JSON response, and it is valid according to JSONLint, but I cannot get the information out of the JSON array into my tables despite following all the examples on Datatables and searching their help site.
please see my code and let me know why this isn't populating the tables.
function populateTable(json, tableId) {
var id = 'table_' + tableId;
console.log("Columns In");
//console.log("table id: " + id + " JSON Response: " + json);
try {
var table = $('#' + id).DataTable({
"data": json.d,
"deferRender": true,
"columns:": [
{ "data ": "CaseHandlerStaffNumber" },
{ "data ": "RiskProfileText" },
{ "data ": "AssignedCheckerStaffNumber" },
{ "data ": "FeedbackUserStaffNumber" },
{ "data ": "ComplaintRef" },
{ "data ": "ChildComplaintRef" },
{ "data ": "CaseTypeText" },
{ "data ": "CheckGrade" }
]
});
} catch (e) {
}
try {
table.columns().every(function () {
var that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this.value) {
that
.search(this.value)
.draw();
}
});
});
} catch (e) {
console.log("Error detected: " + e);
console.log(e);
}
}
-- edit --
this is an example of my JSON data.
{
"data": [{
"CaseHandlerStaffNumber": "12345678",
"RiskProfileText": "Low Risk FOS",
"AssignedCheckerStaffNumber": "77665544",
"FeedbackUserStaffNumber": null,
"ComplaintRef": "999999",
"ChildComplaintRef": "2333",
"CaseTypeText": "FOS Submission",
"CheckGrade": "Ungraded"
}]
}
also, this is how I am producing the JSON
[System.Web.Services.WebMethod()]
public static object GetDataTables(string checkId, int userId)
{
List<string> listOfColumnns = new List<string>();
listOfColumnns.Add("CaseHandlerStaffNumber");
listOfColumnns.Add("RiskProfileText");
listOfColumnns.Add("AssignedCheckerStaffNumber");
listOfColumnns.Add("FeedbackUserStaffNumber");
listOfColumnns.Add("ComplaintRef");
listOfColumnns.Add("ChildComplaintRef");
listOfColumnns.Add("CaseTypeText");
listOfColumnns.Add("CheckGrade");
int checkStatusId = Convert.ToInt32(checkId.Replace("hidJson_tbl_", ""));
TeamChecks tc = new TeamChecks();
DataTable dtMc = default(DataTable);
dtMc = tc.Get_DatatableFor_GridView(userId, checkStatusId);
DataTable dt = new DataTable();
foreach (void colName_loopVariable in listOfColumnns) {
colName = colName_loopVariable;
dt.Columns.Add(string.Format("{0}", colName));
}
foreach (void row_loopVariable in dtMc.Rows) {
row = row_loopVariable;
dt.Rows.Add(row("CaseHandlerStaffNumber"), row("RiskProfileText"), row("AssignedCheckerStaffNumber"), row("FeedbackUserStaffNumber"), row("ComplaintRef"), row("ChildComplaintRef"), row("CaseTypeText"), row("CheckGrade"));
}
string jsonResult = null;
jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(dt);
jsonResult = jsonResult.Replace("[{", "{\"data\" :[{").Replace("}]", "}]}");
return jsonResult;
}
First, make sure you remove extra space at the end of "data" property, e.g.
{ "data": "caseHandlerStaffNumber" },
If your data is in a form of array of objects you need to use "title" property as defined here https://datatables.net/examples/data_sources/js_array.html e.g.
$('#example').DataTable( {
data: dataSet,
columns: [
{ title: "Name" },
{ title: "Position" },
{ title: "Office" },
{ title: "Extn." },
{ title: "Start date" },
{ title: "Salary" }
]
} );
If you're using nuget package, it internally uses Json.NET serializer with an option to lower case first letter of the data set. So, you just need to use lower case when specifying data as follows:
{ "data": "caseHandlerStaffNumber" },
{ "data": "riskProfileText" },
{ "data": "assignedCheckerStaffNumber" },
{ "data": "feedbackUserStaffNumber" },
{ "data": "complaintRef" },
{ "data": "childComplaintRef" },
{ "data": "caseTypeText" },
{ "data": "checkGrade" }

Categories

Resources