How to parse JSON with Newtonsoft? - c#

I created an ASP.NET Application, where I have to parse a csv file with a json structure.
The csv file itself is structured like:
{"Instance":"abc","Date":"2019-06-03T00:00:02.056Z","Identification":"someFunction","Type":"DurationInMs","Value":"5","iserror":"False""}
I get the jsonCsvData as a string and tried to parse it. Then I want to save some of the elements of this json object into a db.
public IActionResult ReadJsonCsvData(string jsonCsvData)
{
Console.WriteLine("ReadJsonCsvData");
ChartData chartData = new ChartData();
var lines = jsonCsvData.Split("\n");
foreach (var line in lines)
{
var values = JObject.Parse(line);
var first = string.Concat(values["Instance"]); //Output for first: ""
}
}
The problem now is, that the variable first is an empty string. The result should be (like in the json structure example above) "abc".
Thank you in advance!

I don't know if it will help but here is my solution (remove one of " at the end of your Json).
I use the "Jobject" to parse Json as I want. Import this two reference.
using Newtonsoft.Json.Linq;
using Newtonsoft;
Then you have to create your JObject :
JObject o = JObject.Parse(myJsonString);
Then to retrieve specifics data, you just have to search in your object just like you do with a dictionary with key :
instanceFromJson = o["Instance"].ToString;
dateFromJson = o["Date"].ToString;
If you have a table in your "instance" json object you can retrieve all data from this list just like that :
foreach (var item in o["Instance"]["tabFromInstanceObject"])
{
MyList.Add(item);
}

Related

Generating Excel file by using LoadFromCollection from a JSON object

I need to produce excel sheet from JSON object.
My JSON object is unknown and can be different from call to call. It have a simple structure (same fields in multiple rows).
I want to use the following code.
workSheet.Cells[2, 1].LoadFromCollection(dataList, false);
dataList input is List (dynamic)
Since my JSON is unknown, I can't define a class for this list (params names and types)
My question is How do I convert a JSON object dynamically to List?
for example I have json object with 3 rows to export:
dataJson -> [{"FirstName":"Yaniv","LastName":"Test","Age": 30,"SubmitDate":"2019-10-04"},{....},{....}]
I need it to be a List dataList -> Count 3
first Item:
Age 30
FirstName "Yaniv"
LastName "Test"
SubmitDate [2019-10-04]
You could deserialise your JSON into a List<Dictionary<string, object>>. For example:
var json = "[{\"FirstName\":\"Yaniv\",\"LastName\":\"Test\",\"Age\": ......]";
var data = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
Now you can extract some details from this list. So to get the column names:
var columnNames = data.First().Keys.ToList();
And loop around your data like this. This will basically output in CSV format, but it should be enough to modify for your needs:
// Write out the column headers
foreach (var columnName in columnNames)
{
Console.Write(columnName + ",");
}
Console.WriteLine();
// Write out each element
foreach (var item in data)
{
foreach (var columnName in columnNames)
{
Console.Write(item[columnName] + ",");
}
Console.WriteLine();
}
This will give output something like this:
FirstName,LastName,Age,SubmitDate,
Yaniv,Test,30,2019-10-04,
Yaniv,Test,30,2019-10-04,
Yaniv,Test,30,2019-10-04,
If you're using Newtonsoft.Json you can deserialize it into a dynamic structure:
var dyn = JArray.Parse("{jsonhere...}");
Then you can read properties like that:
const string json =
"[{\"prop\": 1, \"test\": \"test!\"}, {\"prop\": 2, \"test\": \"test again!\"}, {\"prop\": 3, \"test\": \"one more!\"}]";
var parsed = JArray.Parse(json);
foreach (var value in parsed)
{
var prop = value.Value<int>("prop");
var test = value.Value<string>("test");
Console.WriteLine($"Prop: [{prop}] | Test: [{test}]");
}
Result output will be:
Prop: [1] | Test: [test!]
Prop: [2] | Test: [test again!]
Prop: [3] | Test: [one more!]
Producing excel from JSON input by LoadFromCollection was a bad idea.
The simplest and easiest solution is LoadFromDataTable by convert the JSON to a DataTable:
DataTable data = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(dataJson);
workSheet.Cells[1, 1].LoadFromDataTable(data,true);
Simple as that 😉

FileHelpers DelimitedClassBuilder add fields after read

I'm using the FileHelpers DelimitedClassBuilder to build a class based on metadata in a datatable. This way I can read any file known in the metadata. I read it as a stream and process each record individually. For further processing I want to add some fields to the data and then serialize it to JSON. It's the adding of fields part that doesn't work. The stream returns an object. I'm using a work-around. Serializing the object to JSON, de-serializing it to a dictionary, adding the fields and then serializing it to JSON again. I'm sure this can be done in a more efficient way. I tried converting it to a list but that doesn't work.
//build runtime class based on metadata
FD.DelimitedClassBuilder cb = new FD.DelimitedClassBuilder("ImportFile", "|");
cb.IgnoreFirstLines = 1;
foreach (DT.DataRow drMetadata in dtMetadata.Rows)
{
cb.AddField(drMetadata["EntityColumnName"].ToString(), typeof(string));
cb.LastField.FieldQuoted = true;
cb.LastField.QuoteMode = FH.QuoteMode.AlwaysQuoted;
cb.LastField.QuoteMultiline = FH.MultilineMode.AllowForBoth;
}
//create async filehelper engine for row by row processing
FH.FileHelperAsyncEngine fhe = new FH.FileHelperAsyncEngine(cb.CreateRecordClass());
using (fhe.BeginReadStream(file))
{
foreach(object record in fhe)
{
//convert object to list, doesn't work
//SG.List<object> blaat = (record as SG.IEnumerable<object>).Cast<object>().ToList();
//serialize record class to json
string json = JS.JsonConvert.SerializeObject(record, JS.Formatting.Indented);
//convert message to key-value dictionary
SG.IDictionary<string, string> values = JS.JsonConvert.DeserializeObject<SG.IDictionary<string, string>>(json);
values.Add("SourceSystem", messagesource);
values.Add("SourceType", messagetype);
string json2 = JS.JsonConvert.SerializeObject(values, JS.Formatting.Indented);
SY.Console.WriteLine(json2);
}
}
fhe.Close();
You can use a list of fields obtained via reflection on the record class. Then use Linq's ToDictionary to populate your values.
var recordClass = cb.CreateRecordClass();
List<FieldInfo> fields = recordClass.GetFields().ToList();
FileHelperAsyncEngine fhe = new FileHelperAsyncEngine(recordClass);
using (fhe.BeginReadStream(file))
{
foreach (var record in fhe)
{
IDictionary<string, object> values = fields.ToDictionary(x => x.Name, x => x.GetValue(record));
values.Add("SourceSystem", "messagesource");
values.Add("SourceType", "messagetype");
string json = JsonConvert.SerializeObject(values, Formatting.Indented);
Console.WriteLine(json);
}
}

json add new object to existing json file C#

I'm trying to automate the addition of new objects to an existing JSON file. I looked all around the web but only found adding data and stuff but not a whole object. This is how the file that I want to edit looks:
[
{"id":"123","name":"carl"}
]
and I want to go to
[
{"id":"123","name":"carl"},
{"id":"1234","name":"carl2"}
]
Thank you for all your answers but I don't think everyone completely understands what i mean I have tried some of the answers but then I get this:
[
"{\"id\":\"123\",\"name\":\"carl\"}"
]"{\"id\":\"1234\",\"name\":\"carl2\"}"
and I want everything in between the [].
If you use json.NET you can simply deserialize and serialize the json.
var list = JsonConvert.DeserializeObject<List<Person>>(myJsonString);
list.Add(new Person(1234,"carl2");
var convertedJson = JsonConvert.SerializeObject(list, Formatting.Indented);
Using Json.Net
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
var array = JArray.Parse(initialJson);
var itemToAdd = new JObject();
itemToAdd["id"] = 1234;
itemToAdd["name"] = "carl2";
array.Add(itemToAdd);
var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);
//save to file here
Using this method doesn't require strongly typed objects
You could replace this bit:
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
With
var initialJson = File.ReadAllText(#"c:\myjson.json")
To load the json from a text file
A better performing solution than serializing/deserializing what may be a large file would be to open a FileStream, seek 1 character before the end, then serialize and write your new object into the array, then write a closing bracket. See this question C# How to delete last 2 characters from text file and write into the same line at the end my text?, I'll copy the code here - you already know how to serialize your object and encode it into bytes.
using(var fs = new FileStream("file.json")) {
fs.Seek(-1,SeekOrigin.End);
fs.Write(mySerializedJSONObjAsBytes,0,mySerializedJSONObjAsBytes.Length); // include a leading comma character if required
fs.Write(squareBracketByte, 0, 1);
fs.SetLength(fs.Position); //Only needed if new content may be smaller than old
}
Sorry haven't tested any of that, it's off the top of my head. Pro-tip: wrap FileStream in a StreamWriter so can write strings directly.
You could create a method:
public string AddObjectsToJson<T>(string json, List<T> objects)
{
List<T> list = JsonConvert.DeserializeObject<List<T>>(json);
list.AddRange(objects);
return JsonConvert.SerializeObject(list);
}
Then use it like this:
string baseJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
List<Person> personsToAdd = new List<Person>() { new Person(1234,"carl2") };
string updatedJson = AddObjectsToJson(baseJson, personsToAdd);
this would be a sample for you:
var list = JsonConvert.DeserializeObject<List<Example>>(json);
Example example = new Example();
example.name = "Product2";
example.id="1";
list.Add(example);
string output = JsonConvert.SerializeObject(list);
public class Example
{
public string id {get;set;}
public string name { get; set; }
}
I have been looking for a solution to this exact question for a week now. I finally figured out how to append it to the existing json array and not add it as a solo object after the array. Make sure you are using WriteAllText and not AppendAllText. Here is what I did:
JArray array = JsonConvert.DeserializeObject<JArray (jsonFile);
JObject obj = new JObject();
obj.Add("ID", "123");
obj.Add("Name", "Brian");
array.Add(obj);
var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);
File.WriteAllText("fileName.json", jsonToOutput);

Parsing JToken to get Key Value pair

I'm getting a feed json from YouTube. I can get the "entry" element and the with:
JObject json = JObject.Parse(response);
foreach (var entry in json["feed"]["entry"]) {
var title = entry["title"];
}
But how do I get the Value for 'title'? entry["title].ToString() gives me both key and value as a string...
Please try to include the JSON you want to parse in your question.
That being said, going from the feed shown here, which is linked to from the Developer's Guide: JSON / JavaScript, you should do:
foreach (var entry in json["feed"]["entry"])
{
var title = (string)entry.SelectToken("title.$t");
}

Convert to JSON Array, not regular object

I have used this utility http://www.convertcsv.com/csv-to-json.htm to format tables of data. It has the wonderful option of allowing you to convert to JSON or to a JSON Array. That JSON Array is what I want. When I use utilities like JSON.Net to serialize, they give me the standard JSON format. I don't want that - I just want arrays, so I can basically reproduce a table layout in my javascript.
Here is sample table data structure
column1 column2 column3
c1r1 c2r1 c3r1
c1r2 c2r2 c3r2
c1r3 c2r3 c3r3
I want it to look like this when serialized:
[[c1r1,c2r1,c3r1],
[c1r2,c2r2,c3r2],
[c1r3,c2r3,c3r3]]
But the standard serialization method with a utility like JSON.net would be
[
{
column1:c1r1,
column2:c2r1,
column3:c3r1
},
{
column1:c1r2,
column2:c2r2,
column3:c3r2
},
{
column1:c1r3,
column2:c2r3,
column3:c3r3
}
]
My question is, does anyone know of a way of stripping out column names and just making it like the simple 2d array I have shown?
Data structure is an IEnumerable taken directly from a sql command db.Query("SELECT * FROM my_table").
Note: I want to have a generic function that can do this - I know how to do this for just one thing, but the project I'm working on needs it done for many in the same way. I tried to write my own method to do it, but it didn't work because of limitations that c# has.
public static string fromListToJSONArray(IEnumerable<Object> listToUse, string[] fieldNames)
{
string JSONString = "[";
foreach (var item in listToUse)
{
JSONString += item[fieldName[0]]; //This is the line you can't do in c#!! Don't know how to go around this.
}
JSONString += "]";
return JSONString;
}
What you are trying to output is an array of arrays. Starting with an enumerable or records (in your case it looks like it has columns called column1, column2, column3).
If the query will produce a know result set you can simple convert each row to an array before converting to JSON.
var qry = /*Enumerable of some database query*/
return from rec in wry
select new string[]
{
rec.column1,
rec.column2,
rec.column3
};
I think you're asking something similar to this.
You'll have to assemble the array manually from the json.
I found the solution - IEnumerable type needed to be "dynamic". From there it is pretty simple
public static string fromListToJSONArray(IEnumerable<dynamic> listToUse)
{
string JSONString = "[";
foreach (var item in listToUse)
{
if(isFirst == false)
JSONString += ",";
else
isFirst = false;
JSONString += "\"" + item[0] + "\"";
}
JSONString += "]";
return JSONString;
JSONString += "]";
return JSONString;
}

Categories

Resources