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);
Related
I have a csv file and in one row i have two columns with multiple values .I want to convert that as a list
Example:
CSV data
Id name parentid
1 sam 12-george
24-jennifer
Json Data
[{ id:1, name:sam, parentid:[{ id:12, name:george }, { id:24, name:jennifer }] } ]
class Program
{
const string CSV =
#"Id name parentid
1 sam 12-george
24-jennifer";
static void Main(string[] args)
{
var csvArray = new JArray();
// Split to lines
string[] lines = CSV.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
// Ignore header line
JArray currentParentArray = null;
for (int i = 1; i < lines.Length; i++)
{
string[] items = lines[i].Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (items.Length == 3)
{
var line = new JObject();
csvArray.Add(line);
line["id"] = int.Parse(items[0]);
line["name"] = items[1];
currentParentArray = new JArray();
line["parentid"] = currentParentArray;
ParseParentId(items[2], currentParentArray);
}
if (items.Length == 1 && currentParentArray != null)
ParseParentId(items[0], currentParentArray);
}
var ser = JsonSerializer.CreateDefault();
string json = csvArray.ToString();
Console.WriteLine(json);
Console.ReadKey();
}
static void ParseParentId(string parentId, JArray parentArray)
{
int idx = parentId.IndexOf("-");
string id = parentId.Substring(0, idx);
string name = parentId.Substring(1 + idx);
var obj = new JObject();
obj["id"] = int.Parse(id);
obj["name"] = name;
parentArray.Add(obj);
}
}
This C# source should work. The array of parentid is remembered between lines and added to if the next line contains only another parentid.
Add a Nuget reference to Newtonsoft.Json to compile.
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;
}
Can somebody help me to get the custom JSON string from datatable using C#.
I need something like below.I am able to achive this by using for each loop.
[
{"message": {"alert": "Address Updated"},"target": {"userIds": ["BKAC7759"]}},
{"message": {"alert": "Payment Processed"},"target": {"userIds": ["BKAC7759"]}},
{"message": {"alert": "Notice Sent"},"target": {"userIds": ["BKAC7759"]}}
]
But is there any way i can make it in simple way. My datatable contains values for "alert" and "userIds"
private string GetJsonData(int numberofRecords)
{
// OleDbConnection conn = new OleDbConnection(connectionString);
try
{
DataTable Test = new DataTable("A");
Test.Columns.Add("alert");
Test.Columns.Add("userIds");
Test.Rows.Add("Address Updated", "BKAC7759");
Test.Rows.Add("Payment Made", "BKAC7759");
//Test.Rows.Add("Check Processed", "MAND1884");
//Test.Rows.Add("Notice Mailed", "JAID3869");
//Test.Rows.Add("DL Suspended", "AOQU4798");
string jo = string.Empty;
string com = ",";
int i = 0;
int count = Test.Rows.Count;
string bracketright = "]";
string bracketleft = "[";
foreach (DataRow row in Test.Rows)
{
if (i == 0)
{
jo = jo + bracketleft;
}
jo = jo + "{\"message\":{\"alert\":\"" + row[0].ToString() + "\"},\"target\":{\"userIds\":[\"" + row[1].ToString() + "\"]}}";
if (i != count - 1)
{
jo = jo + com;
}
else
{
jo = jo + bracketright;
}
i++;
}
return jo;
}
catch (Exception ex)
{
Logger.Error("GetJsonData(int numberofRecords): " + ex.Message);
return string.Empty;
}
finally
{
// always close the connection.
// conn.Close();
}
}
You can use Linq + DataTableExtensions (in namespace System.Data and system DLL System.Data.DataSetExtensions.dll) to transform your table into an enumerable of anonymous types, then serialize that to JSON with json.net.
I notice your "userIds" property is a JSON array. Do you want all the user userIds for a given alert to be combined? If so, you can use ToLookup to combine them:
var root = dataTable.AsEnumerable()
.ToLookup(r => r["alert"].ToString(), r => r["userIds"].ToString())
.Select(g => new { message = new { alert = g.Key }, target = new { userIds = g } });
var json = JsonConvert.SerializeObject(root);
If not, do:
var root = dataTable.AsEnumerable()
.Select(r => new { message = new { alert = r["alert"].ToString() }, target = new { userIds = new [] { r["userIds"].ToString() } } });
var json = JsonConvert.SerializeObject(root);
For the following table:
var dataTable = new DataTable("A");
dataTable.Columns.Add("alert");
dataTable.Columns.Add("userIds");
dataTable.Rows.Add("Address Updated", "BKAC7759");
dataTable.Rows.Add("Payment Made", "BKAC7759");
dataTable.Rows.Add("Address Updated", "MAND1884");
dataTable.Rows.Add("Payment Made", "MAND1884");
The first produces the following JSON:
[
{"message":{"alert":"Address Updated"},"target":{"userIds":["BKAC7759","MAND1884"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["BKAC7759","MAND1884"]}}
]
And the second produces the following:
[
{"message":{"alert":"Address Updated"},"target":{"userIds":["BKAC7759"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["BKAC7759"]}},
{"message":{"alert":"Address Updated"},"target":{"userIds":["MAND1884"]}},
{"message":{"alert":"Payment Made"},"target":{"userIds":["MAND1884"]}}
]
I need to return an array of arrays instead of an array of objects for a flot chart.
I can get the following:
data = [{"2012-10": 4140},{"2012-11": 10815},{"2012-12": 10444}];
but need (UPDATE fixed following line):
data = [["2012-10", 4140],["2012-11", 10815],["2012-12", 10444]];
Here is the c# which is parsing inbound json from another source:
public async Task<ActionResult> Chart(string custid)
{
//Get the financial results from DRT
var response = await DominoJSON.getJSON(custid, "drtHistory", "DRT");
JArray UOVol = new JArray();
var array = JArray.Parse(response);
foreach (var token in array)
{
JObject o = JObject.Parse(token.ToString());
int uovol = Convert.ToInt32(o["UOVol"]);
string uodate = o.SelectToken("DATE").ToString();
JObject UOItem = new JObject(new JProperty(uodate, uovol));
UOVol.Add(UOItem);
}
string resultUO = UOVol.ToString();
ViewBag.UOData = resultUO;
return View();
}
And the inbound json being parsed:
[
{
"DATE":"2012-10",
"UOVol":4140,
"FIRev":180,
"AFRev":692.75,
"ABRev":2900,
"OWRev":3791.25,
},
{
"DATE":"2012-11",
"UOVol":10815,
"FIRev":60,
"AFRev":170,
"ABRev":0,
"OWRev":3037.5,
},
{
"DATE":"2012-12",
"UOVol":10444,
"FIRev":40,
"AFRev":514.25,
"ABRev":1450,
"OWRev":7500,
}
]
I can't figure out how to turn the JObjects to arrays. I have tried this with other approaches including using a dictionary and list. Any help or alternate solutions would be helpful. Using VS2013, mvc 5 and EF 6.
Try this:
class Program
{
static void Main(string[] args)
{
string jsonIn = #"
[
{
""DATE"": ""2012-10"",
""UOVol"": 4140,
""FIRev"": 180,
""AFRev"": 692.75,
""ABRev"": 2900,
""OWRev"": 3791.25
},
{
""DATE"": ""2012-11"",
""UOVol"": 10815,
""FIRev"": 60,
""AFRev"": 170,
""ABRev"": 0,
""OWRev"": 3037.5
},
{
""DATE"": ""2012-12"",
""UOVol"": 10444,
""FIRev"": 40,
""AFRev"": 514.25,
""ABRev"": 1450,
""OWRev"": 7500
}
]";
JArray arrayIn = JArray.Parse(jsonIn);
JArray arrayOut = new JArray();
foreach (JObject jo in arrayIn.Children<JObject>())
{
JArray ja = new JArray();
ja.Add(jo["DATE"]);
ja.Add(jo["UOVol"]);
arrayOut.Add(ja);
}
string jsonOut = arrayOut.ToString(Formatting.None);
Console.WriteLine(jsonOut);
}
}
Output:
[["2012-10",4140],["2012-11",10815],["2012-12",10444]]
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));
}