how to replace property values in a dynamic JSON? - c#

I'm reading my json file from and trying to replace the property values. JSON file is below.
{
"fields": {
"summary": "summaryValue",
"project": {
"key": "projectValue"
},
"priority": {
"name": "priorityValue"
},
"Requestor": {
"name": "RequestorValue"
},
"issue": {
"name": "issueValue"
},
"labels": "LabelValue",
"customfield_xyz": "customfield_xyzValue"
}
}
How can I replace the value for each item inside the fields property ?
for ex:
{"fields": {
"summary": "NewsummaryValue",
"project": {
"key": "NewprojectValue"
},
"priority": {
"name": "NewpriorityValue"
}
}
}
Below is the code to parse my json file,
StreamReader r = new StreamReader(filepath);
var jsondata = r.ReadToEnd();
var jobj = JObject.Parse(jsondata);
foreach (var item in jobj.Properties())
{
\\replace code
}

I do not know exactly what you want. But I changed the json information in the code snippet as you wanted.
dynamic dataCollection = JsonConvert.DeserializeObject<dynamic>(jsonData);
string summary = dataCollection["fields"]["summary"];
string project = dataCollection["fields"]["project"]["key"];
string priority = dataCollection["fields"]["priority"]["name"];
dynamic json = new JObject();
json.summary = summary;
json.project = project;
json.priority = priority;
dynamic jsonRoot = new JObject();
jsonRoot.fields = json;
Console.WriteLine(jsonRoot.ToString());
output:

Related

C# Directory path to json formatting

I'm trying to save a folder path in a json file but I can't seem to find/figure out how to get it to parse it correctly
I'm using the following code to write the json file
string location = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string userDataPreset = #"{UserData: [{Language: ""NL"", location: " + location + "}]}";
File.WriteAllText(userData, userDataPreset);
This creates the following json:
{
"UserData": [
{
"Language": "NL",
"location": C:\Users\stage\OneDrive\Documenten
}
]
}
But I need it to become the following, with the double // and "":
{
"UserData": [
{
"Language": "NL",
"location": "C:\\Users\\stage\\OneDrive\\Documenten"
}
]
}
What am I missing to parse this path correctly?
to fix the string you can use an Escape method
location=Regex.Escape(location);
but the most relable method is to create an anonymous object and serialize it
var data = new { UserData = new[] { new { Language = "NL", Location = location } } };
var json = System.Text.Json.JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true});
File.WriteAllText(userData, json);
json
{
"UserData": [
{
"Language": "NL",
"Location": "C:\\Users\\stage\\OneDrive\\Documenten"
}
]
}

How can I search a JSON file in C# by a key value, and then obtain a subsequent key + value?

I have 3 JSON files that all contain the same data structure, however different data.
The structure for all 3 files is as follows:
{
"TokenId": "0",
"rank": "2804"
},
{
"TokenId": "1",
"rank": "977"
},
{
"TokenId": "2",
"rank": "4085"
}
I am trying to create a new JSON file from these 3 files that has the following structure, and yes, they all have the same tokenID values, but slightly different rank values:
{
"TokenId": "0",
"File1Rank": "2804",
"File2Rank": "2802",
"File3Rank": "2809"
},
{
"TokenId": "1",
"File1Rank": "977",
"File2Rank": "983",
"File3Rank": "999"
},
{
"TokenId": "2",
"File1Rank": "4085",
"File2Rank": "4089",
"File3Rank": "4100"
}
How can I search by the tokenId value in each file to obtain the rank value? I can iterate through each valuea in each file to get both values, but I am struggling to create or update the new JSON correctly. The logic I feel I need is if the TokenId is equal to a certain value, then add the rank key/value, but I have not been able to find the answer on how I can do this.
You can use the newtonsoft json library to parse and update the json files.
If your source file structure is:
{
"Tokens": [
{
"TokenId": "0",
"rank": "2804"
},
{
"TokenId": "1",
"rank": "977"
},
{
"TokenId": "2",
"rank": "4085"
}
]
}
Pseudo code:
using Newtonsoft.Json
using Newtonsoft.Json.Linq
void Main()
{
dynamic objFinal = JObject.Parse("{ 'Tokens':[] }");
JArray finalArray = (JArray)objFinal["Tokens"];
DirectoryInfo dir = new DirectoryInfo(#"D:\Projects\JsonFiles\");
foreach(var file in dir.GetFiles("*.json"))
{
dynamic objJson = JObject.Parse(File.ReadAllText(file.FullName));
JArray tokens = (JArray)objJson["Tokens"];
foreach(JToken token in tokens)
{
JToken searchResult = finalArray.Where(t=> Convert.ToString(t["TokenId"])==Convert.ToString(token["TokenId"])).FirstOrDefault();
if(searchResult==null)
{
//push new tokenid
JArray newFileRanks = new JArray();
newFileRanks.Add(token["rank"]);
dynamic newToken = new JObject();
newToken["TokenId"] = token["TokenId"];
newToken["fileRanks"] = newFileRanks;
finalArray.Add(newToken);
}
else
{
//append to fileRanks
JArray existingFileRanks = (JArray)searchResult["fileRanks"];
dynamic fileRankExists = existingFileRanks.Where(t=> Convert.ToString(t)==Convert.ToString(token["rank"])).FirstOrDefault();
if(fileRankExists==null)
{
existingFileRanks.Add(token["rank"]);
}
}
}
}
Console.Write(JsonConvert.SerializeObject(objFinal));
}
Final output:
{
"Tokens": [
{
"TokenId": "0",
"fileRanks": [ "2804", "2801" ]
},
{
"TokenId": "1",
"fileRanks": [ "977", "972" ]
},
{
"TokenId": "2",
"fileRanks": [ "4085", "4083" ]
}
]
}

how to work with nested json object in c#

api return json which is nested and i dont know to retrieve data from it and map it to my model. i want to retrieve the data from nested but not sure how to do this with index and value. Thanks in Advance.
public class MikesExcelModel
{
//public int id;
//public object AuthorizingManagerId;
public string Name;
//public DateTime UpdateDate;
public string Phone;
public string Email;
}
public class MikesExcelResults
{
public List<MikesExcelModel> value = new List<MikesExcelModel>();
}
public List<MikesExcelModel> GetExcel()
{
using (HttpClient client = new HttpClient())
{
addToken(client);
var result = client.GetAsync("https://graph.microsoft.com/beta/sites/ucfdev.sharepoint.com,4c319763-130d-4ee1-bc1f-72543da0a847,8a2f59f4-9d56-4aec-be21-33d0347293d1/drives/b!Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m/items/01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH/workbook/worksheets('sheet1')/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows").Result;
if (result.IsSuccessStatusCode)
{
var responseContent = result.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
JavaScriptSerializer serialiser = new JavaScriptSerializer();
// dynamic apiResult = serialiser.DeserializeObject(responseString);
return Utilities.DeserializeObject<MikesExcelResults>(result.Content.ReadAsStringAsync().Result).value;
}
else
throw new Exception("Couldn't get excel datas.");
}
}
}
Data return by api looks like this:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets('sheet1')/tables('%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D')/rows",
"value": [
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=0)",
"index": 0,
"values": [
[
"Mike Callahan",
"407-266-1431",
"MTC#ucf.edu"
]
]
},
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=1)",
"index": 1,
"values": [
[
"Michael Callahan",
"407-823-3455",
"mtcallah#ucf.edu"
]
]
},
{
"#odata.id": "/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=2)",
"index": 2,
"values": [
[
"cvcfcv",
"zVCCvc",
"cvvvvb"
]
]
}
]
}
Maybe traditional way to extract JSON data with Newtonsoft.Json library.
Convert jsonData to JObject (via JObject.Parse).
Get first-level value.
Get second-level values.
Flatten second-level values.
From
[[["Mike Callahan", "407-266-1431", "MTC#ucf.edu"], ...]]
To
[["Mike Callahan", "407-266-1431", "MTC#ucf.edu"], ...]
Convert flattenChildrenValues to List<MikesExcelModel>.
Add List<MikesExcelModel> to results.value
using System;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
var jsonData = #"{
""#odata.context"": ""https://graph.microsoft.com/beta/$metadata#sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets('sheet1')/tables('%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D')/rows"",
""value"": [
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=0)"",
""index"": 0,
""values"": [
[
""Mike Callahan"",
""407-266-1431"",
""MTC#ucf.edu""
]
]
},
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=1)"",
""index"": 1,
""values"": [
[
""Michael Callahan"",
""407-823-3455"",
""mtcallah#ucf.edu""
]
]
},
{
""#odata.id"": ""/sites('ucfdev.sharepoint.com%2C4c319763-130d-4ee1-bc1f-72543da0a847%2C8a2f59f4-9d56-4aec-be21-33d0347293d1')/drives('b%21Y5cxTA0T4U68H3JUPaCoR_RZL4pWnexKviEz0DRyk9HjXtfo70gjRbH706GdwO5m')/items('01HA4SXKSESD3RW3UYPNCZ2OHQAEWWDTKH')/workbook/worksheets(%27%7B00000000-0001-0000-0000-000000000000%7D%27)/tables(%27%7B079215E2-A6D7-4CC2-AB1E-9AC38F36D1CC%7D%27)/rows/itemAt(index=2)"",
""index"": 2,
""values"": [
[
""cvcfcv"",
""zVCCvc"",
""cvvvvb""
]
]
}
]
}";
var jsonObj = JObject.Parse(jsonData);
// Get first-level value
JArray jsonValue = jsonObj["value"] as JArray;
// Get second-level values
var childrenValues = jsonValue.Children<JObject>()["values"];
// Flatten second-level values
var flattenChildrenValues = childrenValues.Values<JArray>() as IEnumerable<JArray>;
// Read flattenChildrenValues to List<MikesExcelModel>
List<MikesExcelModel> excelModels = flattenChildrenValues
.Select(x => new MikesExcelModel
{
Name = x[0].ToString(),
Phone = x[1].ToString(),
Email = x[2].ToString()
})
.ToList();
// Add List<MikesExcelModel> to results.value
MikesExcelResults results = new MikesExcelResults();
results.value.AddRange(excelModels);
foreach (var model in results.value)
{
Console.WriteLine(String.Format("Name: {0}, Phone: {1}, Email: {2}", model.Name, model.Phone, model.Email));
}
Sample program

CSV to Nested JSON C#

I would like to convert a csv file into json with nested objects and nested array. The sample csv looks like below. My csv structure can be dynamic, but I am ok to keep it static to get the required format below. I know there are so many answers to similar questions, but none addressing my specific issue of nested objects.
Id,name,nestedobject/id,nestedarray/0/name
1,name,2,namelist
2,name1,3,namelist1
I want the json like below, specifically having trouble with column 3 & 4 (nested objects)
[{"Id": 1,
"name": "name",
"nestedobject": {
"id": 2
},
"nestedarray": [{
"name": "namelist"
}
]
},
{"Id": 2,
"name": "name1",
"nestedobject": {
"id": 3
},
"nestedarray": [
{"name": "namelist1"}]
}
]
Please note to keep the csv file structure dynamic I pass the datatype in the column name - for e.g.. "System.Int32:Id" will be my first column instead of "Id". How can I modify my code to account for the nested objects?
public static DataTable ReadCsvFile(string fileName)
{
DataTable oDataTable = new DataTable();
StreamReader oStreamReader = new StreamReader(fileName);
bool hasColumns = false;
List<string> ColumnNames = new List<string>();
string[] oStreamDataValues = null;
while (!oStreamReader.EndOfStream)
{
String oStreamRowData = oStreamReader.ReadLine();
if(oStreamRowData.Length > 0)
{
oStreamDataValues = oStreamRowData.Split(',');
if(!hasColumns)
{
int i = 0;
foreach(string csvcolumn in oStreamRowData.Split(','))
{
string[] nameWithType = csvcolumn.Split(':');
DataColumn oDataColumn = new DataColumn(nameWithType[1], typeof(string));
ColumnNames.Add(nameWithType[1]);
var type = System.Type.GetType(nameWithType[0]);
oDataColumn.DataType = type;
oDataTable.Columns.Add(oDataColumn);
i = i + 1;
}
hasColumns = true;
}
else
{
DataRow oDataRow = oDataTable.NewRow();
for(int i = 0; i < ColumnNames.Count; i++)
{
oDataRow[ColumnNames[i]] = oStreamDataValues[i] == null ? string.Empty : oStreamDataValues[i].ToString();
}
oDataTable.Rows.Add(oDataRow);
}
}
}
oStreamReader.Close();
oStreamReader.Dispose();
return oDataTable;
}
I serialize the DataTable in the end
DataTable dt = ReadCsvFile(filePath);
dt.CaseSensitive = true;
var jsonData = JsonConvert.SerializeObject(dt);
With Cinchoo ETL, an open source library, you can do it as follows
string csv = #"Id,name,nestedobject/id,nestedarray/0/name, nestedarray/0/city, nestedarray/1/name, nestedarray/200/city
1,name,2,namelist10, citylist10,namelist11, citylist11
2,name1,3,namelist20, citylist20,namelist21, citylist21";
StringBuilder json = new StringBuilder();
using (var w = new ChoJSONWriter(json))
{
using (var r = ChoCSVReader.LoadText(csv).WithFirstLineHeader()
.Configure(c => c.NestedColumnSeparator = '/')
)
w.Write(r);
}
Console.WriteLine(json.ToString());
Output:
[
{
"Id": 1,
"name": "name",
"nestedobject": {
"id": 2
},
"nestedarray": [
{
"name": "namelist10",
"city": "citylist10"
},
{
"name": "namelist11"
}
]
},
{
"Id": 2,
"name": "name1",
"nestedobject": {
"id": 3
},
"nestedarray": [
{
"name": "namelist20",
"city": "citylist20"
},
{
"name": "namelist21"
}
]
}
]

C# MongoDb - Output id field properly?

I don't understand how can I output id properly when displaying objects. It's either ObjectId() that I can't parse back to object or some object that has id in it that I can parse but it looks weird.
Note that mapping it to class is not an option, it needs to be fully dynamic because different users have different fields.
Code
public List<object> Get()
{
var client = new MongoClient("mongodb://localhost");
var server = client.GetServer();
var database = server.GetDatabase("api_test");
var collection = database.GetCollection("users");
var json = collection.FindAllAs<BsonDocument>().ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });
var obj = JsonConvert.DeserializeObject<List<object>>(json);
return obj;
}
Example
[
{
"_id": {
"$oid": "528e7f9bb1fece903aa9b246"
},
"Name": "Steve",
"Age": 60
},
{
"_id": {
"$oid": "528e7fabb1fece903aa9b247"
},
"Name": "Alice",
"Age": 44
}
]
What I would like
[
{
"_id": "528e7f9bb1fece903aa9b246",
"Name": "Steve",
"Age": 60
},
{
"_id": "528e7fabb1fece903aa9b247",
"Name": "Alice",
"Age": 44
}
]
You can do this by explicitly updating your query result to convert _id to a string before it's serialized to JSON:
var docs = test.FindAll().ToList();
foreach (var doc in docs)
{
doc["_id"] = doc["_id"].ToString();
}
var json = docs.ToJson(
new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });

Categories