My Json looks like below.
I want to check if the following key/nodes exist or not in the below Json.
1st node-> AutomationFramework.Technique.Available
2nd node->Verify.Customer
{
"$type": "Config",
"Available": true,
"Verify": {
"$type": "UserList`2"
"Customer":"Peter"
},
"Identification": true,
"Verification": false,
"AutomationFramework": [
{
"$type": "custom",
"Name": "ATL",
"Technique": {
"$type": "Technique",
"PropertyName": "Name",
"Available": true
},
"SolveTechnique": {
"$type": "Userdefined",
"Available": true
},
"AITechnique": {
"$type": "AI",
"X_Value": 2,
"Y_Value": 3,
"Available": true
},
"WaitTechnique": {
"$type": "Recurssion",
"Available": true
}
}
]
}
I tried with the following code (ParseJson below is a method to parse JSON which I have created):
JObject obj = JObject.Parse(ParseJson(#"C:\Test\Test.Config"));
IEnumerable<JToken> token = obj.SelectTokens("AutomationFramework.Technique.Available", errorWhenNoMatch: false);
Here it is returning null even if the node is present.
I want a generic method that could handle all scenarios. Any help will be appreciated.
The method should return True/False based on the existence.
Your code is not working because AutomationFramework is a list, not an object.
Also, be sure to cast the result to an appropriate type. If you know the type of the token, you can cast directly in place. If you don't know the type at compile time, you can store in a JToken variable instead.
In your code you are using SelectTokens. But if you are expecting only one of that token, you should use SelectToken instead.
Assuming that the desired node Technique will always be present in the first item of the AutomationFramework list, you could do:
JObject obj = JObject.Parse(ParseJson(#"C:\Test\Test.Config"));
bool avail = (bool)obj.SelectToken("AutomationFramework[0].Technique.Available", errorWhenNoMatch: false);
string cust = (string)obj.SelectToken("Verify.Customer", errorWhenNoMatch: false);
Related
I have the following json called 'originalJson'
{
"user_active": true,
"user_firstname": "Bob",
"user_lastname": "Tester",
"user_displayname": "Bobby",
"user_primary_email": "bob#tester.com",
"user_login_enabled": true,
"user_profile": {
"user_locale": "en-gb",
"user_lang": "en-gb"
},
"user_identities": [],
"user_roles": [
{
"app_id": "74a019c9-7171-4af0-a773-3984edaa35ca",
"context_uuid": "74a019c9-7171-4af0-a773-3984edaa35ca",
"context_type": "context_application",
"role_oid": "test_role_a",
"role_start_date": "2020-06-27T13:00:00Z",
"role_end_date": "2021-06-27T13:00:00Z"
}
]
}
and I am trying to replace the role_start_date and role_end_date values.
I have tried the following
JObject jObj = JObject.Parse(originalJson);
jObj["user_roles"]["role_start_date"] = somenewstartDate;
jObj["user_roles"]["role_end_date"] = somenewendDate;
However it is failing and doesn't like the "jObj["user_roles"]["role_start_date"]". I thought it would be pretty simple to do, I must be missing something.
Any ideas?
The property "user_roles" is an array of objects not a single object. You are trying to set a property value in the first entry in that array, so you need to do:
jObj["user_roles"][0]["role_start_date"] = somenewstartDate;
jObj["user_roles"][0]["role_end_date"] = somenewendDate;
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();
I am making rest call and receving following JSON response:
{
"issues": [{
"id": "250271",
"self": "KeyUrl1",
"key": "Key-8622",
"fields": {
"attachment": [{
"self": "AttachmentUrl1",
"id": "106198",
"filename": "export.htm"
}
],
"customfield_11041": "Test"
}
},
{
"id": "250272",
"self": "KeyUrl2",
"key": "Key-8621",
"fields": {
"attachment": [{
"self": "AttachmentUrl2",
"id": "106199",
"filename": "lmn.htm"
}
],
"customfield_11041": "Test"
}
},
]
}
I parsed it using NewtonSoft Json to JObject.
var jObject = JObject.Parse(response);
Further I am trying to filter such records where either attachment is missing or none of the attachments contain filename like "export".
Following is the code I have written, ideally it should result in just 1 record in the records object, however its returning both the objects.
var issues = jObject["issues"] as JArray;
var records = issues.Where(x => !x["fields"]["attachment"].Any() || !x["fields"]["attachment"].Any(y => y["filename"].Contains("export")));
Need help to figure out whats going wrong.
Here's fiddle link - https://dotnetfiddle.net/AVyIHr
The problem is that you're calling Contains("export") on the result of y["filename"], which isn't a string - it's a JToken. You need to convert to a string first, to use the form of Contains that you're expecting.
Additionally, you can get rid of the first condition - an issue with no attachments doesn't have any attachments with "export" filename anyway.
That leaves this:
var records = issues
.Where(x => !x["fields"]["attachment"].Any(y => ((string) y["filename"]).Contains("export")))
.ToList();
You may well find it's simpler to deserialize to a class, however - that will reduce the risk of typos and the risk of this sort of conversion error. If you deserialized to a List<Issue> you'd have a condition of:
x => !x.Fields.Attachments.Any(y => y.Filename.Contains("export"))
... which I think is rather cleaner.
var records = issues.Where(x => !x["fields"]["attachment"].Any() || !x["fields"]["attachment"].Any(y => y["filename"].ToString().Contains("export"))).ToList();
Add .ToString() will resolve the issue.
How can i acces the first item id?
using (var http = new HttpClient())
{
var res = JArray.Parse(await http.GetStringAsync("http://api.champion.gg/champion/Gragas?api_key=????").ConfigureAwait(false));
^^^^^^ // Also tried with JObject instead of JArray, both don't work
var champion = (Uri.EscapeUriString(res[0]["items"][0]["mostGames"][0]["items"][0]["id"].ToString()));
Console.WriteLine(champion); // ^ [0] here because the JSON starts with an [
}
Example JSON result (made it smaller because the original JSON is over 21500 characters, made sure its valid with https://jsonlint.com, here is the original JSON response: https://hastebin.com/sacikozano.json)
[{
"key": "Gragas",
"role": "Jungle",
"overallPosition": {
"change": 1,
"position": 13
},
"items": {
"mostGames": {
"items": [{
"id": 1402,
"name": "Enchantment: Runic Echoes"
},
{
"id": 3158,
"name": "Ionian Boots of Lucidity"
},
{
"id": 3025,
"name": "Iceborn Gauntlet"
},
{
"id": 3065,
"name": "Spirit Visage"
},
{
"id": 3742,
"name": "Dead Man's Plate"
},
{
"id": 3026,
"name": "Guardian Angel"
}
],
"winPercent": 50.45,
"games": 300
}
}
}]
With JArray i get the following error: Accessed JObject values with invalid key value: 0. Object property name expected.
With JObject i get the following error: Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
Thanks in advance, i hope i explained it well
It should be:
var champion = (Uri.EscapeUriString(res[0]["items"]["mostGames"]["items"][0]["id"].ToString()));
The outermost "items" property has a single object as its value, not an array, so [0] is not needed in ["items"][0]. Similarly "mostGames" has a single object value so the [0] is not needed in ["mostGames"][0].
Sample fiddle.
Note that if "items" is sometimes an array of objects, but sometimes is a single object instead of an array of one object, you can introduce the following extension method:
public static class JsonExtensions
{
public static IEnumerable<JToken> AsArray(this JToken item)
{
if (item is JArray)
return (JArray)item;
return new[] { item };
}
}
And do:
var champion = (Uri.EscapeUriString(res[0]["items"].AsArray().First()["mostGames"]["items"][0]["id"].ToString()));
I am storing data in my cassandra database as string and i want to retrieve the string and convert it into json. i get an exception saying
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException' happened
is there something wrong with the data stored ? or i am doing some other thing wrong ?
My query is :
INSERT INTO table2(key1,col1) values ('5',{'url':'{"hello":
{"hi":{"hey":"1","time":"5"}},
{"reg":{"hey":"1","time":"1"}},
{"install":{"hey":"0"}}},
"task":"1","retry":"00",
"max":"5","call":"140"'});
In my db when i click the map<text,text> column, it gets stored as :
{\"hello\":\r\n
{\"subscription_atrisk\":{\"hey\":\"1\",\"time\":\"100\"}},
{\"reg\":{\"hey\":\"1\",\"time\":\"2000\"}},
\"task\":\"0\",\"retry\":\"300\",\"max\":\"5\",\"call\":\"14400\"}
in my c# code, i try
string s = "{\"hello\":\r\n {\"subscription_atrisk\":{\"hey\":\"1\",\"time\":\"100\"}},{\"reg\":{\"hey\":\"1\",\"time\":\"2000\"}},\"task\":\"0\",\"retry\":\"300\",\"max\":\"5\",\"call\":\"14400\"";
Jobject json = Jobject.Parse(s); //Get an Error here.
Could anyone please throw some light on this ?
In JSON, an object should contain a key and either a value or another object/array.
You have syntax errors in your JSON object. First of all, always use double quotes.
Then... The url object has a key Hello but then where you are supposed to place two more keys, you're just putting there two more objects, as if it was an array.
This could be a correct syntax:
{
"url": {
"hello": {
"hi": {
"hey": "1",
"time": "5"
}
},
"MissingKey1":{
"reg": {
"hey": "1",
"time": "1"
}
},
"MissingKey2":{
"install": {
"hey": "0"
}
}
},
"task": "1",
"retry": "00",
"max": "5",
"call": "140"
}
Or if you really meant to have a hello object and an array of two more objects inside url:
{
"url": {
"hello": {
"hi": {
"hey": "1",
"time": "5"
}
},
"AnArray": [{
"reg": {
"hey": "1",
"time": "1"
}
}, {
"install": {
"hey": "0"
}
}]
},
"task": "1",
"retry": "00",
"max": "5",
"call": "140"
}
I suggest that before you store those JSON objects in the database, ALWAYS validate them to make sure that they're valid of syntax.
Or even better: this Newtonsoft library provides functions which serializes(creates) JSON strings from other objects. See JsonConvert.SerializeObject Method
In general it is a good idea to look around in the API documentation, it really can save you a lot of time so that you don't have to do unnecessary work.
Looks like you're missing a closing }
Try:
string s = "{\"hello\": {\"subscription_atrisk\":{\"hey\":\"1\",\"time\":\"100\"}}, \"missing_key\": {\"reg\":{\"hey\":\"1\",\"time\":\"2000\"}},\"task\":\"0\",\"retry\":\"300\",\"max\":\"5\",\"call\":\"14400\"}";