Convert Single column C# DataTable to JSON using JSON.NET - c#

The DataTable contains single column EFFDATE.
EFFDATE
2015-06-15
2014-10-21
2014-07-17
2014-07-16
2014-06-17
2014-03-13
I have the following code to convert DataTable dttbl to JSON.
JsonConvert.SerializeObject(dttbl, Formatting.Indented)
The output from conversion is
[
{
"EFFDATE": "2015-06-15"
},
{
"EFFDATE": "2014-10-21"
},
{
"EFFDATE": "2014-07-17"
},
{
"EFFDATE": "2014-07-16"
},
{
"EFFDATE": "2014-06-17"
},
{
"EFFDATE": "2014-03-13"
}
]
The output I want is
{
"EFFDATE": [
"2015-06-15",
"2014-10-21",
"2014-07-17",
"2014-07-16",
"2014-06-17",
"2014-03-13"
]
}
Please advice.

var json = JsonConvert.SerializeObject(
new { EFFDATE = dt.AsEnumerable().Select(r => r[0]) }
);

Related

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" ]
}
]
}

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"
}
]
}
]

How to bind data to JSON file based on #para-id

In my project client send me this JSON string.
{
"onlineRequest": {
"CustomerCode": "AB432A",
"MobileNumber": "75484568",
"ProductNo": "100",
"JsonFile": {
"evaluation": {
"number": [
{
"#para-id": "5656",
"#new-code": "",
"#text": "Hello America"
},
{
"#para-id": "3302",
"#new-code": "100",
"#text": "Hello Japan"
}
]
}
}
}
}
This JSON contains inner JSON called JsonFile. Now I need to set the values to this JSON file as follows.
if #para-id = 5656, then #new-code = "0000"
if #para-id = 3302, then #new-code = "1111"
Expected Output:
{
"onlineRequest": {
"CustomerCode": "AB432A",
"MobileNumber": "75484568",
"ProductNo": "100",
"JsonFile": {
"evaluation": {
"number": [
{
"#para-id": "5656",
"#new-code": "0000",
"#text": "Hello America"
},
{
"#para-id": "3302",
"#new-code": "1111",
"#text": "Hello Japan"
}
]
}
}
}
}
How can I do this?
Can be easily done with Newtonsoft.Json:
var source = #"{
""onlineRequest"": {
""CustomerCode"": ""AB432A"",
""MobileNumber"": ""75484568"",
""ProductNo"": ""100"",
""JsonFile"": {
""evaluation"": {
""number"": [
{
""#para-id"": ""5656"",
""#new-code"": """",
""#text"": ""Hello America""
},
{
""#para-id"": ""3302"",
""#new-code"": ""100"",
""#text"": ""Hello Japan""
}
]
}
}
}
}";
var json = JToken.Parse(source);
var dict = new Dictionary<string, string>
{
["5656"] = "0000",
["3302"] = "1000",
};
foreach (var number in json.SelectToken("onlineRequest.JsonFile.evaluation.number").ToArray())
{
var id = (string)number["#para-id"];
if (id != null && dict.TryGetValue(id, out var code))
{
number["#new-code"] = code;
}
}

Group a json data into list based on key trailing number

I got a json result as shown in image 1 but I need an output shown in image 2.
I took the following classes
public class NameDTO
{
public string Name;
}
public class ValDTO
{
public string Val;
}
I got the list to the above classes as shown in figure 3 and 4 and combining them and converting to json.
var combined1 = _nameDetials1.Zip(_valDetials1, (name1, val1) => new { name1.Name, val1.Val }) .ToDictionary(k => k.Name, k => k.Val);
var jsonSerialiser1 = new JavaScriptSerializer();
var json1 = jsonSerialiser1.Serialize(combined1);
How can I do the grouping so that I can get he correct output as shown in image2
Thanks.
If it is possible you can use Json.NET.
Here an example to solve your problem.
const string JSON = #"{
""message-Code-1"": ""000"",
""msg-Number-Pos1-1"": ""0000"",
""msg-Number-Pos2-1"": ""1"",
""msg-Number-Pos3-1"": ""1"",
""message-Code-2"": ""1"",
""msg-Number-Pos1-2"": ""0001"",
""msg-Number-Pos2-2"": ""2"",
""msg-Number-Pos3-2"": ""1"",
""message-Code-3"": ""0002"",
""msg-Number-Pos1-3"": ""3"",
""msg-Number-Pos2-3"": ""1"",
""msg-Number-Pos3-3"": ""1"",
""message-Code-4"": ""0003"",
""msg-Number-Pos1-4"": ""3"",
""msg-Number-Pos2-4"": ""1"",
""msg-Number-Pos3-4"": ""1""
}";
JObject loMessages = JObject.Parse(JSON);
JArray loMessageArray = new JArray();
JObject loAddMessage;
foreach (var loMessageGroup in loMessages.Properties().GroupBy(item => Regex.Match(item.Name,#".*-(?<pos>\d+)").Groups["pos"].Value))
{
loAddMessage = new JObject();
foreach (var loMessage in loMessageGroup)
loAddMessage[loMessage.Name] = loMessage.Value.ToString();
loMessageArray.Add(loAddMessage);
}
Console.WriteLine(loMessageArray.ToString());
The Json Ouput is like this:
[
{
"message-Code-1": "000",
"msg-Number-Pos1-1": "0000",
"msg-Number-Pos2-1": "1",
"msg-Number-Pos3-1": "1"
},
{
"message-Code-2": "1",
"msg-Number-Pos1-2": "0001",
"msg-Number-Pos2-2": "2",
"msg-Number-Pos3-2": "1"
},
{
"message-Code-3": "0002",
"msg-Number-Pos1-3": "3",
"msg-Number-Pos2-3": "1",
"msg-Number-Pos3-3": "1"
},
{
"message-Code-4": "0003",
"msg-Number-Pos1-4": "3",
"msg-Number-Pos2-4": "1",
"msg-Number-Pos3-4": "1"
}
]

parsing json with using json.net linq

I tray to parse json with using Json.Net but i am new parsing json and i didn't get good result after so many test.
json structure is as below;
[
{
"Coo":{
"id":"1"
},
"Hor":{
"name":"Poo"
},
"Vor":{
"name":"Soo"
},
"Status":"1",
"Tola":[
{
"value":"10",
},
{
"value":"20",
}
],
"Opt":[
]
},
{
"Coo":{
"id":"2"
},
"Hor":{
"name":"Zoo"
},
"Vor":{
"name":"Koo"
},
"Status":"2",
"Tola":[
{
"value":"20",
},
{
"value":"10",
}
],
"Opt":[
]
},
{
"Coo":{
"id":"3"
},
"Hor":{
"name":"Moo"
},
"Vor":{
"name":"Noo"
},
"Status":"1",
"Tola":[
{
"value":"30",
},
{
"value":"20",
}
],
"Opt":[
]
}
]
My code is as below for parsing.
_JsonString = _JsonString.Trim().Trim('[',']');
JObject _JObject = JObject.Parse(_JsonString);
var _JItems = _JObject.SelectToken(".")
.Select(s => new
{
_Id = (string)s.SelectToken("Coo.id"),
_WhereClause = (string)s.SelectToken("Status")
})
.Where(w => w._WhereClause == "1");
foreach (var _JItem in _JItems)
{
MessageBox.Show(_JItem._Id.ToString());
}
Thank you in advance.
You are using JObject while you should use JArray:
Remove this line:
_JsonString = _JsonString.Trim().Trim('[', ']'); /*removed*/
And change
JObject _JObject = JObject.Parse(_JsonString);
To
JArray _JObject = JArray.Parse(_JsonString);
Full code:
JArray _JObject = JArray.Parse(_JsonString);
var _JItems = _JObject.SelectToken(".")
.Select(s => new
{
_Id = (string)s.SelectToken("Coo.id"),
_WhereClause = (string)s.SelectToken("Status")
})
.Where(w => w._WhereClause == "1");
foreach (var _JItem in _JItems)
{
MessageBox.Show(_JItem._Id.ToString());
}

Categories