How to update a property of a JSON object using NewtonSoft - c#

I have a JSON string like this:
{
"code": "GENDER",
"value": { "option": "ML" }
}
I would like to update the option property to "Male" if the value is "ML" and "Female" if the value is "FM".
I have got to this point, but am unsure how to proceed:
JArray contentobject = (JArray)JsonConvert.DeserializeObject(contentJSON);
JObject voicgObj = contentobject.Children().FirstOrDefault(ce => ce["code"].ToString() == "GENDER") as JObject;
JProperty voicgProp = voicgObj.Property("value");
I don't know how to get to the option which is a child of value.
Thanks in advance. Any pointers would be great.

You can access the object by using properties as keys:
JObject obj = JObject.Parse(json);
string gender = (string)obj["value"]["option"];
For your example, try:
JObject obj = JObject.Parse(json);
var val = obj["value"];
string option = (string)val["option"];
if (option == "ML")
val["option"] = "Male";
if (option == "FM")
val["option"] = "Female";
string result = obj.ToString();

Another way, with minimal property retrieving:
var val = voicgObj["value"] as JObject;
JProperty optionProp = val.Property("option");
string option = optionProp.Value.Value<string>();
if (option == "ML")
optionProp.Value = "Male";
else if (option == "FM")
optionProp.Value = "Female";

Related

Searching and deleting a node from JSON

JSON is holding a data.
I need to remove the node where the "id" value matches passed in value. In the below code var isRemoved = (dataDeserialized as JArray).Remove(index); is returning false. The node is not deleted. How can i delete the node?
The property name "id" is even dynamic. It will get passed in. How can i check the property name along with value (current) to find the index?
Here is what i have so far:
var entityJson = #"
[
{
'id': 1,
'code': 'abc1'
},
{
'id': 2,
'code': 'abc2'
}
]".Replace("'", "\"");
var dataDeserialized = JsonConvert.DeserializeObject<dynamic>(entityJson);// DataLoader.DeserializeJson(entityJson, false);
if(dataDeserialized.Count > 0)
{
var key = "id";
var value = "2";
var index = 0;
var isFound = false;
foreach(var d in dataDeserialized)
{
if((string)d.id == value.ToString())
{
isFound = true;
break;
}
index++;
}
if (isFound)
{
var isRemoved = (dataDeserialized as JArray).Remove(index);
if (isRemoved)
{
var setting = new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.None,
};
var resul = JsonConvert.SerializeObject(dataDeserialized, setting);
//var result = JsonHelper.SerializeObject(dataDeserialized);
}
}
}
I have tried jObject as well but it is giving an error Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 2, position 13
dynamic obj = JObject.Parse(entityJson);
(obj.employees as JArray).RemoveAt(0);
Update #1: here is what worked for me for #1 above
if(dataDeserialized.Count > 0)
{
var key = "id";
var value = "2";
JArray list = new JArray();
foreach (var d in dataDeserialized)
{
if ((string)d.id != value.ToString())
{
list.Add(d);
}
}
if(list.Count > 0)
{
var result = JsonConvert.SerializeObject(list);
}
}
Still, how can i do #2, checking the "key"?
If you don't want to deserialize this json to a strongly typed object, I would recommend working with the JObject and JArray classes from the Newtonsoft.Json package because they are much more flexible for this purpose.
So you can easily remove a node from the json with a dynamic key like this:
string key = "id";
int id = 2;
var entityJson = #"
[
{
""id"": 1,
""code"": ""abc1""
},
{
""id"": 2,
""code"": ""abc2""
},
{
""id"": 3,
""code"": ""abc3""
}
]";
JArray jarray = JArray.Parse(entityJson);
var item = jarray.Children().Where(i => (int)(i as JObject).GetValue(key) == id).SingleOrDefault();
if (item != null)
{
jarray.Remove(item);
}
var resul = JsonConvert.SerializeObject(jarray);

How to convert JSON to an anonymous object if I don't know the data structure?

Is it possible to convert JSON to an anonymous object if I don't have a model?
Here's an example with a model:
var json = "{\"firstName\": \"John Doe\", \"lastName\": \"Doe\"}";
var model = new { firstName = "", lastName = "" };
var result = JsonConvert.DeserializeAnonymousType(json, model);
//result: { firstName = John Doe, lastName = Doe }
How to do the same if I don't know the data structure like in the example?
The problem is I'm actually using some library and it doesn't work if I pass a dynamic object as a parameter.
The only way the method I need to work is passing an anonymous object like:
instance.SomeMethod(new { firstName = "John", lastName = "Doe" })
You can use dynamic with DeserializeObject:
var json = "{\"firstName\": \"John Doe\", \"lastName\": \"Doe\"}";
var result = JsonConvert.DeserializeObject<dynamic>(json);
var firstName = result.firstName;
You can use dynamic type but you will need to includes a reference named Microsoft.CSharp if working in Xamarin.
Here's the example:
var json = "{\"firstName\": \"John Doe\", \"lastName\": \"Doe\"}";
dynamic x = JsonConvert.DeserializeObject(json);
Console.WriteLine(x.firstname.ToString());
//You'll need to convert to data type especially in boolean, int, float, double
And here's to convert object to json:
dynamic x = new ExpandoObject();
x.param1 = "";
x.param2 = "";
string json = JsonConvert.SerializeObject(x);
Using dynamic:
var json = "{\"firstName\": \"John Doe\", \"lastName\": \"Doe\"}";
dynamic result = JsonConvert.DeserializeObject(json);
Also you can check if the property exists before access to it and avoid crashes with this code:
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(result .ToString());
if (dictionary.ContainsKey("firstName"))
//do something with "firstName"
Hope it works
In System.Dynamic namespace, there is a sealed class named ExpandoObject. If you are using Newtonsoft.Json library, it will do it for you. You don't need to know data structure at runtime.
var json = "{\"firstName\": \"John\", \"lastName\": \"Doe\"}";
var obj = JsonConvert.DeserializeObject<ExpandoObject>(json);
var returnData = new ReturnData(){
Id = 1,
Value = "Hello",
State = true,
Json = obj
};
return returnData;
Output:
{
"id": 1,
"value": "Hello",
"state": true,
"json": {
"firstName": "John",
"lastName": "Doe"
}
}
Tested with .NET 6, works properly.
Try to use GSon, you should import the dependency

How to Modify JSON object inside JSON array in c#?

This is my Json Array
[
{
"gregdate": "06-03-2019",
"maldate": "22-07-1194",
"gregmonth": "March",
"selected_status": "1"
},
{
"gregdate": "04-05-2019",
"maldate": "21-09-1194",
"gregmonth": "May",
"selected_status": "1"
},
{
"gregdate": "03-06-2019",
"maldate": "20-10-1194",
"gregmonth": "June",
"selected_status": "1"
}
]
In this JSON Array, I want to change 2nd JSON Object "selected_status" value "1" to "0" without changing the position of the JSON Object.
You need to first convert you object array to JArray and then change its second object property from 1 to 0 like
string json = "You json here"; //Load your json
JArray jArray = JArray.Parse(json); //Parse it to JArray
var jObjects = jArray.ToObject<List<JObject>>(); //Get list of objects inside array
foreach (var obj in jObjects) //Loop through on a list
{
if (jObjects.IndexOf(obj) == 1) //Get 2nd object from array
{
foreach (var prop in obj.Properties()) //List 2nd objects properties
{
if (prop.Name == "selected_status") //Get desired property
obj["selected_status"] = 0; //Change its value
}
}
}
JArray outputArray = JArray.FromObject(jObjects); //Output array
Alternative:
As suggested by Brian Rogers you can directly query your JArray to replace its specific property value like,
string json = "You json here"; //Load your json
JArray jArray = JArray.Parse(json); //Parse it to JArray
jArray[1]["selected_status"] = "0"; //Querying your array to get property of 2nd object
string outputJson = jArray.ToString(); //Output json
Output: (from debugger)
This question helped me figure a couple things out - so here is what I came up with. I'm guessing that the json is a sample and what is desired is changing the status for a specific date, rather than just the second element. At least that's what I've been looking for. This is more dynamic and you don't have to worry about the position of the element.
string newJson = "";
if (SwitchStatus(jsonString, "04-05-2019", "0", out newJson))
{
Console.Write(newJson);
}
else
{
Console.WriteLine("Date Not Found");
}
Console.ReadLine();
static bool SwitchStatus(string jsonString, string searchBy, string switchTo, out string output)
{
dynamic jsonObj = JsonConvert.DeserializeObject(jsonString);
JToken status = jsonObj.SelectToken($"$..[?(#.gregdate == '{searchBy}')].selected_status");
if (status != null)
{
status.Replace(switchTo);
output = JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
}
else
{
output = jsonString;
}
return status != null;
}

How to get value by key from JObject?

I have a JObject like this:
{
"#STARTDATE": "'2016-02-17 00:00:00.000'",
"#ENDDATE": "'2016-02-18 23:59:00.000'"
}
I want to get #STARTDATE and #ENDDATE value from JObject.
This is a sample code that I've tried to do the task:
JObject json = JObject.Parse("{\"#STARTDATE\": \"'2016-02-17 00:00:00.000'\",\"#ENDDATE\": \"'2016-02-18 23:59:00.000'\"}");
var key = "#STARTDATE";
var value = GetJArrayValue(json, key);
private string GetJArrayValue(JObject yourJArray, JToken key)
{
string value = "";
foreach (JToken item in yourJArray.Children())
{
var itemProperties = item.Children<JProperty>();
//If the property name is equal to key, we get the value
var myElement = itemProperties.FirstOrDefault(x => x.Name == key.ToString());
value = myElement.Value.ToString(); //It run into an exception here because myElement is null
break;
}
return value;
}
Note: The code above cannot get the value by key from JObject.
Could you help me to find a way to get the value by key from JObject?
This should help -
var json = "{'#STARTDATE': '2016-02-17 00:00:00.000', '#ENDDATE': '2016-02-18 23:59:00.000' }";
var fdate = JObject.Parse(json)["#STARTDATE"];
You can also get the value of an item in the jObject like this:
JToken value;
if (json.TryGetValue(key, out value))
{
DoSomething(value);
}
Try this:
private string GetJArrayValue(JObject yourJArray, string key)
{
foreach (KeyValuePair<string, JToken> keyValuePair in yourJArray)
{
if (key == keyValuePair.Key)
{
return keyValuePair.Value.ToString();
}
}
}

Using JSON.NET to add a boolean property

I have this JSON data
{
"extensions": {
"settings" : {
"extension1": {
"property1": "value 1",
"property2": "value 2"
}
}
}
}
my goal is to add a new boolean property using JSON.NET to look like this
{
"extensions": {
"settings" : {
"extension1": {
"property1": "value 1",
"property2": "value 2",
"bool_property": true
}
}
}
}
I only have this code and I'm stuck with AddAfterSelf and AddBeforeSelf
string pref = "path_of_the_preferences_file";
string _pref = string.empty;
using (StreamReader reader = new StreamReader(pref, Encoding.UTF8))
{
_pref = reader.ReadToEnd();
}
// REFORMAT JSON.DATA
JObject json = JObject.Parse(_pref);
var extension1 = json["extensions"]["settings"]["extension1"];
How do I insert the new boolean property "bool_property" ?
Thanks
A JObject is essentially a dictionary. Just get a reference to the object you wish to add the property to and add it.
var propertyName = "bool_property";
var value = true;
var obj = JObject.Parse(json);
var extension1 = obj.SelectToken("extensions.settings.extension1") as JObject;
if (extension1 != null)
{
extension1[propertyName] = value;
}
If you're targeting .NET 4 and up, you know the structure of the json and the name of the property you wish to add, you can use dynamic here.
var value = true;
dynamic obj = JObject.Parse(json);
obj.extensions.settings.extension1.bool_value = value;
You can even mix and match.
var propertyName = "bool_property";
var value = true;
dynamic obj = JObject.Parse(json);
obj.extensions.settings.extension1[propertyName] = value;
Deserialize your JSON, add a property and serialize it back into a string.
dynamic sourceJson = JsonConvert.DeserializeObject(json, typeof(object));
sourceJson.extensions.settings.extension1.bool_property = false;
var modifiedJson = JsonConvert.SerializeObject(sourceJson, Formatting.Indented);
I got it
string pref = "path_of_the_preferences_file";
string _pref = string.empty;
using (StreamReader reader = new StreamReader(pref, Encoding.UTF8))
{
_pref = reader.ReadToEnd();
}
// REFORMAT JSON.DATA
JObject json = JObject.Parse(_pref);
var extension1 = json["extensions"]["settings"]["extension1"];
var a = extension1.Children();
JProperty cond_it = null;
foreach (var b in a)
{
if (b.ToString().ToLower().Contains("cond_it"))
{
cond_it = (JProperty)b;
break;
}
}
if (cond_it != null)
{
var b = cond_it.Value.SelectToken("location").Parent;
b.AddAfterSelf(new JProperty("blacklist", true));
}

Categories

Resources