Need to merge two json objects using c# based on spectific condition. If source JSON has "Enabled" property as "false" and destination JSON has same property as "true", then need to replace the value. Other wise no need to replace keep as same.
I tried like this :
o1.Merge(o2, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Merge
});
its overlapping the whole Object. Need to merge based on condition. Thanks in advance.
JSON 1:
{
"Name": "Sample",
"Array": [],
"Actions": [
{
"Name": "A",
"Enabled": false
},
{
"Name": "B",
"Enabled": true
}
]
}
JSON 2 :
{
"Name": "Sample",
"Array": [],
"Actions": [
{
"Name": "A",
"Enabled": true
},
{
"Name": "B",
"Enabled": false
}
]
}
I need Result JSON as below.
{
"Name": "Sample",
"Tabs": [],
"Actions": [
{
"Name": "A",
"Enabled": true
},
{
"Name": "B",
"Enabled": true
}
]
}
If source JSON has "Enabled" property as "false" and destination JSON has same property as "true", then need to replace the value. Other wise no need to replace keep as same.
One approach would be to,
Loop through Actions array in the destination json.
Read each object's Name and Enabled from the above array.
Retrieve the same object from source json.
Read its Name and Enabled.
Check whether property Name of both objects from json match and also check Enabled property of object from source json is false and Enabled property of object from destination json is true.
Rewrite the value of the property Enabled to true.
string json1 = "Your source json";
string json2 = "Your destination json";
JObject jObject1 = JObject.Parse(json1);
JObject jObject2 = JObject.Parse(json2);
//1
foreach (JObject obj2 in (JArray)jObject2["Actions"])
{
//2
var key2 = obj2["Name"].ToObject<string>();
var value2 = obj2["Enabled"].ToObject<bool>();
//3
var obj1 = jObject1["Actions"].Where(x => x["Name"].ToString() == key2).FirstOrDefault();
//4
var key1 = obj1["Name"].ToObject<string>();
var value1 = obj1["Enabled"].ToObject<bool>();
//5
if (key1 == key2 && value1 == false && value2 == true)
{
//6
obj2["Enabled"] = true;
}
}
string outputJson = jObject2.ToString();
Related
Given a JSON array of:
[
{
"id": 1,
"name": "abc"
},
{
"id": 2
},
{
"id": 3,
"name": "def"
}
]
I would expect:
JArray jArray = JArray.Parse(json);
dynamic value = jArray.SelectTokens("$[?(#['name'] == null || #['name'] == 'abc')]");
to produce:
[
{
"id": 1,
"name": "abc"
},
{
"id": 2
}
]
This tests correctly using a variety of online JsonPath testers. But when I run it with Json.NET, I am getting:
[
{
"id": 1,
"name": "abc"
}
]
Is it possible for me to change the JsonPath to handle this? Is it the null in the query that is the problem?
For clarity, I need to use JsonPath because it is stored in a configuration file and applied dynamically.
I expect that Newtsoft is considering absence to be different from "present with a null value," whereas the others you've tried consider them to be the same.
I imagine if you update the path to
$[?(!#['name'] || #['name'] == null || #['name'] == 'abc')]
it might work for you.
Alternatively, updating the data to
[
{
"id": 1,
"name": "abc"
},
{
"id": 2,
"name": null
},
{
"id": 3,
"name": "def"
}
]
would also yield the middle item.
We haven't defined this yet in the specification effort, but it's a good one. I'll raise that in an issue.
You can also see there's no consensus among libraries with this test.
With LINQ to JSON you can solve the same problem like this:
var json = File.ReadAllText("sample.json");
var semiParsedJson = JArray.Parse(json);
var filteredJson = from item in semiParsedJson
let name = (string)item["name"]
where name == null || name == "abc"
select item;
Console.WriteLine(new JArray(filteredJson));
The output will be as expected:
[
{
"id": 1,
"name": "abc"
},
{
"id": 2
}
]
I've this JSON object
{
"08f4f705-6e14-4781-8241-d04bf2dc6ada": {
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
"05f4f995-6e14-4567-8241-d04bf2d456ee": {
"description": "aaaaaa",
"note": "bbb"
},
"0675f995-6e14-4567-8241-d4567f2d456z": {
"description": "fffff",
"note": "gggg"
}
}
I need to convert into a JSON array like this:
(the elements should be the content of the first level properties)
[
{
"description": "xxxxxxxx",
"note": "yyyyyyyy"
},
{
"description": "aaaaaa",
"note": "bbb"
},
{
"description": "fffff",
"note": "gggg"
}
]
I can't manipulate the object and I didn't find an appropriate resource to follow. How can I do it?
You can achieve this by deserializing your json string into Dictionary<string, object>:
var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
After that you extract the values and serialize them back to json:
var newJson = JsonConvert.SerializeObject(obj.Values);
When the cube is created and sum is chosen it returns a sum and a count in the value context when output as json. How can that be turned off so only the sum value is returned?
//define cube pivot
var cubeData = new PivotData(
new[] { "CloseDate", "StageName", "Type", "OpportunityName","Industry", "IsClosed", "IsWon" },
new SumAggregatorFactory("Amount"),
true);
json = new
{
cubeData,
};
return json;
Output shows
"cubeData": [
{
"key": [
"2019-07-05T00:00:00",
"Stage Value",
"Type Value",
"Opportunity Name Value",
"Industry Value",
false,
false
],
"value": {
"value": 35000.0,
"count": 1
}
},
PivotData has 2 serializable properties:
Count and Value.
If you want to prevent Value from being serialized, you would need to modify the PivotData class to [JsonIgnore] the Count property.
Alternatively, depending on your json implementation you can just remove the "count" element before returning.
json = new
{
cubeData,
};
json["value"].Value<JObject>().Remove("count");
return json;
I am using dynamic ExpandoObject() to create some json required for an NVD3/d3.js visualisation.
The nvd3 library is pretty explicit in what it needs with regards to data identifiers.
Exactly the json i need is the following -
[{
key: "AgeGroups",
values: [{
"label": "<20",
"value": 0
}, {
"label": ">20 <29",
"value": 160
}, {
"label": ">29 <39",
"value": 240
}]
}]
Note: the string 'key' must be lowercase and values must be pluralized.
With the following c#, I am able to get very close -
ageDemoJson.AgeGroups = new object[]
{
new { label = "<20", value = lessThan20 },
new { label = ">20 <29", value = between20and29 },
new { label = ">29 <39", value = between29and39 },
};
This outputs the following
[{
Key: "AgeGroups",
Value: [{
"label": "<20",
"value": 0
}, {
"label": ">20 <29",
"value": 160
}, {
"label": ">29 <39",
"value": 240
}]
}]
With this output, I need to customise the default behaviour of ExpandoObject and make the string 'Key' become 'key' and the string 'value' become 'values'
Is there anyway of doing this?
Of course I can work around this by parsing the json to string and replacing what I need in javascript, but would like if I didn't have to do that.
If you're using asp.net core you can change the JSON serialization by adding this line:
services.AddMvc()
.AddJsonOptions(opts =>
{
// Force Camel Case to JSON
opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
Or you can achive the same result by using Newtonsoft's Json.NET with this option:
string json = JsonConvert.SerializeObject(
yourObjectToSerialize,
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);
Lets say i have the following JSON
{
"data": [
{
"from": {
"name": "aaa bbb",
},
"actions": [
{
"name": "Comment",
"link": "http://...
},
{
"name": "Like",
"link": "http://.."
}
],
},
And i have
JSONObject wallData = helper.Get("/me/feed");
if (wallData != null)
{
var data = wallData.Dictionary["data"];
List<JSONObject> wallPosts = data.Array.ToList<JSONObject>();
}
foreach (Facebook.JSONObject wallItem in wallPosts)
{ ... }
Which stores me whole feed into wallData and 'data' object into wallPosts.
So then i can access the wallItem.Dictionary["from"].Dictionary["name"], and i get "aaa bbb".
But i can't get inside the actions array
The wallItem.Dictionary["actions"].Dictionary["name"] doesn't work.
Any idea
You need to do something like wallItem.Dictionary["actions"][0].Dictionary["name"] because "actions" is an array.
On a different note...its neater if u directly into a class...like this
var jSerializer = new JavaScriptSerializer();
var jsonObject = jSerializer.Deserialize<DataObject>(json);
The DataObject will be a class which emulates ur JSON data in a strongly typed class. Depending on the size of ur Json you will not have to use a lot of strings in your code.