While converting json string datatable facing an issue with , (comma) value in value field.
actualy my json string is [{"BNo":"345","GNo":"3453","FirstName":"fjai","LastName":"ljai","Address":"BARETI,CEVO, 13/2","Telephone":"051682247","BirthDate":"23-Jan-1981","Email":""}]
In that please look at the address scenario "Address":"BARETI,CEVO, 13/2"
It has the , in the values field. While converting the string to data base i got error. Here the code which i used convert json string to datatable
public DataTable JsonStringToDataTbl(string jsonString)
{
DataTable dt = new DataTable();
string[] jsonStringArray = Regex.Split(jsonString.Replace("[", "").Replace("]", ""), "},{");
List<string> ColumnsName = new List<string>();
foreach (string jSA in jsonStringArray)
{
string[] jsonStringData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
foreach (string ColumnsNameData in jsonStringData)
{
try
{
int idx = ColumnsNameData.IndexOf(":");
string ColumnsNameString = ColumnsNameData.Substring(0, idx - 1).Replace("\"", "");
if (!ColumnsName.Contains(ColumnsNameString))
{
ColumnsName.Add(ColumnsNameString);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Error Parsing Column Name : {0}", ColumnsNameData));
}
}
break;
}
foreach (string AddColumnName in ColumnsName)
{
dt.Columns.Add(AddColumnName);
}
foreach (string jSA in jsonStringArray)
{
string[] RowData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
DataRow nr = dt.NewRow();
foreach (string rowData in RowData)
{
try
{
int idx = rowData.IndexOf(":");
string RowColumns = rowData.Substring(0, idx - 1).Replace("\"", "");
string RowDataString = rowData.Substring(idx + 1).Replace("\"", "");
nr[RowColumns] = RowDataString;
}
catch (Exception ex)
{
continue;
}
}
dt.Rows.Add(nr);
}
return dt;
}
The code must omit the , in the value field.. what can i do
If your keys are unknown at the time of being read, then you can use the JObject and the JProperty classes from JSON.Net to retrieve the keys and their values like this:
private void printKeysAndValues(string json)
{
var jobject = (JObject)((JArray)JsonConvert.DeserializeObject(json))[0];
foreach (var jproperty in jobject.Properties())
{
Console.WriteLine("{0} - {1}", jproperty.Name, jproperty.Value);
}
}
Applied to two different JSON input string, retrieves the key/value pair:
var json1 = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
var json2 = #"[{""Test"": ""A"", ""Text"":""some text"", ""Numbers"":""123""}]";
printKeysAndValues(json1);
Console.WriteLine("-------------------");
printKeysAndValues(json2);
And the output is:
BNo - 345
GNo - 3453
FirstName - fjai
LastName - ljai
Address - BARETI,CEVO, 13/2
Telephone - 051682247
BirthDate - 23-Jan-1981
Email -
-------------------
Test - A
Text - some text
Numbers - 123
One possibility would be to use the dynamic keyword. You can directly access the field like this:
var json = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
dynamic data = JsonConvert.DeserializeObject(json);
// take the first element of the array
string address = data[0].Address;
Console.WriteLine(address.Replace(",", " "));
The output is:
BARETI CEVO 13/2
Note that String.Replace does not fail, if the symbol that should be replaced is not currently present, so "test".Replace(",", " "); will return test.
Another possibility is to use the in ASP.NET build in JSON converter (serializer/deserializer) - NewtonSoft JSON.Net. You can use it in order to regain the structured data. You need to create a class that represents the JSON structure:
public class Data
{
public string BNo { get; set; }
public string GNo { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Telephones { get; set; }
public string BirthDates { get; set; }
public string Emails { get; set; }
}
Then the current JSON can be converted to an object of type Data using the JsonConvert.DeserializeObject method:
var json = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
// remove square braces [ and ] at the start resp. end
var data = JsonConvert.DeserializeObject<Data>(json.Substring(1).Substring(0, json.Length - 2));
Now you can access the Address field and for example replace the , symbol:
Console.WriteLine(data.Address.Replace(",", " "));
The output is:
BARETI CEVO 13/2
I think your service returns also the wrong JSON format. JSON always starts with an object (when not in JavaScript), meaning that everything at the top level must be enclosed within curly braces { and }. If the service should return an array, then it should look like this {"results": [{"BNo":"...},{...}]}. If you can't change the service, then you can adapt / correct the returned string. Add a typed model for the array:
public class DataHolder
{
public Data[] data { get; set; }
}
and then create a correct JSON object holding an array:
var data = JsonConvert.DeserializeObject<DataHolder>("{\"data\":" + json + "}");
Console.WriteLine(data.data[0].Address.Replace(",", " "));
The output is again the same.
You can convert the JSON value to C# objects using Newtonsoft. This would be easy for you. Once you have converted to the below object, you can easily modify the Address property to remove the ',' value.
public class RootObject
{
public string BNo { get; set; }
public string GNo { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Telephone { get; set; }
public string BirthDate { get; set; }
public string Email { get; set; }
}
Use the below line to convert to C# object
var jsonString = "The output of your webservice";
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
Now obj instance holds the C# object which is very easy to manipulate.
Related
I have this JSON string called assignee:
{
"id": 15247055788906,
"gid": "15247055788906",
"name": "Bo Sundahl",
"resource_type": "user"
}
I want to get the "name" element and its value if it's not null. I have tried
var jobject = JsonConvert.DeserializeObject<JObject>(assignee);
And
var jo = JObject.Parse(assignee);
I tried looping through it but I just get null exception or empty output even though if I just print the assignee variable itself its filled with data.
My loop is like:
foreach (var result in jobject["name"])
{
Debug.WriteLine(result);
}
The simplest and best way is to deserialise to a C# class, for example:
public class Data
{
public long Id { get; set; }
public string Name { get; set; }
//etc..
}
And deserialise like this
var data = JsonConvert.DeserializeObject<Data>(json);
var name = data.Name;
To get name use this
string name = jobject["name"];
Using ["name"] returns a JToken, it is null if the property doesn't exist
JToken token = jo["name"];
Debug.WriteLine(token?.ToString() ?? "<default value>");
If you don't know properties beforehand, you can loop through JObject properties and get name value pairs as following:
var jsonObject = JObject.Parse(str);
foreach (var item in jsonObject)
{
var name = item.Key;
JToken token = item.Value;
if (token is JValue)
{
var value = token.Value<string>();
}
}
Here is how it should work:
class Data
{
public long? Id { get; set; }
public string Gid { get; set; }
public string Name { get; set; }
public string Resource_Type { get; set; }
}
class Program
{
static void Main(string[] args)
{
string assignee = "{\"id\": 15247055788906, \"gid\": \"15247055788906\", \"name\": \"Bo Sundahl\", \"resource_type\": \"user\"}";
Data data = JsonConvert.DeserializeObject<Data>(assignee);
Console.WriteLine(data.Id);
Console.WriteLine(data.Gid);
Console.WriteLine(data.Name);
Console.WriteLine(data.Resource_Type);
Console.ReadLine();
}
}
How to query some json to select a specific property?
EX: If I have Json obj like this :
[
{
"grd_symbol":"A+",
"count":21.23,
"code":4,
"name":"X",
"batch_no":760
},
{
"grd_symbol":"A ",
"count":11.93,
"code":4,
"name":"X",
"batch_no":760
},
{
"grd_symbol":"A-",
"count":8.49,
"code":4,
"name":"X",
"batch_no":760
}
]
This's the output of :
string JsonObj = Converter.ConvertDataTabletoString(DT);
public static string ConvertDataTabletoString(DataTable dt)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
Dictionary<string, object> row;
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
rows.Add(row);
}
return serializer.Serialize(rows);
}
Now I want to get the count only,The result will be like this:
[21.23,11.93,8.49]
Take a look at Newtonsoft.JSON.
Using this, we can create an object to match the json string:
public class MyCustomObject
{
[JsonProperty("grd_symbol")] public string GridSymbol {get; set;}
[JsonProperty("count")] public double Count {get; set;}
[JsonProperty("code")] public int Code {get; set;}
[JsonProperty("name")] public string Name {get; set;}
[JsonProperty("batch_no")] public int BatchNumber {get; set;}
}
Then you can deserialize your json using the library mentioned above:
var myData = JsonConvert.DeserializeObject<MyCustomObject[]>(jsonString);
And then, since you want an array of the counts, you can use LINQ to get them using Select:
var countArray = myData.Select(x => x.Count);
And of course, if you want to output this as a string, you can just serialize it again:
var countString = JsonConvert.SerializeObject(countArray);
You don't even have to to deserialise all property to select just one you can simple omit the unwanted one in the calss definition so they will be ignored.
Using :
public class SimplifyRootObject
{
public double count { get; set; }
}
Instead of :
public class RootObject
{
public string grd_symbol { get; set; }
public double count { get; set; }
public int code { get; set; }
public string name { get; set; }
public int batch_no { get; set; }
}
Then a simple string.Join() to add the comma and there you are.
$"[{string.Join("_separator_", myListOfDouble)}]"
MCVE:
public static void Main(string[] args)
{
string input = #"[
{
""grd_symbol"":""A+"",
""count"":21.23,
""code"":4,
""name"":""X"",
""batch_no"":760
},
{
""grd_symbol"":""A "",
""count"":11.93,
""code"":4,
""name"":""X"",
""batch_no"":760
},
{
""grd_symbol"":""A-"",
""count"":8.49,
""code"":4,
""name"":""X"",
""batch_no"":760
}
]";
// Deserialize All, select the wanted.
var m = JsonConvert.DeserializeObject<List<RootObject>>(input);
var result = m.Select(x=> x.count);
Console.WriteLine("["+string.Join(", ", result)+"]");
// Deserialize only one, select it.
var m2 = JsonConvert.DeserializeObject<List<SimplifyRootObject>>(input);
var result2 = m.Select(x=> x.count);
Console.WriteLine("["+string.Join(", ", result2)+"]");
}
}
https://rextester.com/PFJZN10272;
The label of your topic is "how to do a projection on json string" and you're telling us that you already have a DataTable that you want to convert into a string.
The code you gave us though means "I want to serialize my datatable into a JSON string".
In the end, what do you even need ? An array of string ? a string ? a json object ?
If it's a string, i would suggest you to override the ToString() method of DataTable to get the format you want i.e [number1, number2, number3] by fetching the datatable and returning a STRING and not a JSON.
Edit. #ThePerplexedOne has answered the question, i think.
I am trying to deserialize a JSON array that has an additional nested object.
Here is a sample C# code. It returns data until it gets to the second array. I know it needs a second foreach loop but I can't seem to get it to work. Any help would be greatly appreciated. Thank you.
string sJSON = #" [{""dateNumeric"":1216000000,""hourOfDay"":0,""customerNumber"":12,""storedepartment"":[{""department"":333,""descriptionOfDepartment"":""Department A""},{""department"":111,""descriptionOfDepartment"":""Department B""}]},{""dateNumeric"":1216000000,""hourOfDay"":3,""customerNumber"":3,""storedepartment"":[{""department"":999,""descriptionOfDepartment"":""Department X""},{""department"":888,""descriptionOfDepartment"":""Department Y""}]}]";
JArray a = JArray.Parse(sJSON);
foreach (JObject o in a.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = (string)p.Value;
Console.WriteLine(name + "-- " + value);
}
}
You can use Newtonsoft.json library for serializing/deserializing the data, as per your requirement kindly follow below code :
First you need to create the class which will capture the data in specified format(as per your data requirement) :
public class RootObject
{
public int dateNumeric { get; set; }
public int hourOfDay { get; set; }
public int customerNumber { get; set; }
public List<Storedepartment> storedepartment { get; set; }
}
public class Storedepartment
{
public int department { get; set; }
public string descriptionOfDepartment { get; set; }
}
Now , for deserialising the Json data use below statement :
string sJSON = #" [{""dateNumeric"":1216000000,""hourOfDay"":0,""customerNumber"":12,""storedepartment"":[{""department"":333,""descriptionOfDepartment"":""Department A""},{""department"":111,""descriptionOfDepartment"":""Department B""}]},{""dateNumeric"":1216000000,""hourOfDay"":3,""customerNumber"":3,""storedepartment"":[{""department"":999,""descriptionOfDepartment"":""Department X""},{""department"":888,""descriptionOfDepartment"":""Department Y""}]}]";
List<RootObject> Data = JsonConvert.DeserializeObject<List<RootObject>>(sJSON);
Once you get data in your list you can perform your required operation on list
Actually you might be able to properly parse your JSON string if you use the following approach.
public static void ProcessJObject(JProperty obj)
{
string name = obj.Name;
string value = "";
if (obj.Value.Type == JTokenType.Array)
{
Console.WriteLine("Array: " + name);
ProcessJArray((JArray)obj.Value);
}
else
{
value = (string)obj.Value;
Console.WriteLine(name + "-- " + value);
}
}
public static void ProcessJArray(JArray arr)
{
foreach (JObject o in arr.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
ProcessJObject(p);
}
}
}
static void Main(string[] args)
{
string sJSON = #" [{""dateNumeric"":1216000000,""hourOfDay"":0,""customerNumber"":12,""storedepartment"":[{""department"":333,""descriptionOfDepartment"":""Department A""},{""department"":111,""descriptionOfDepartment"":""Department B""}]},{""dateNumeric"":1216000000,""hourOfDay"":3,""customerNumber"":3,""storedepartment"":[{""department"":999,""descriptionOfDepartment"":""Department X""},{""department"":888,""descriptionOfDepartment"":""Department Y""}]}]";
JArray a = JArray.Parse(sJSON);
ProcessJArray(a);
Console.Read();
}
So what have I done here. I simply divided the problem of parsing json in two smaller problems one that is solved by the ProcessJObject function (parsing and printing JProperty) and one that is solved by the ProcessJArray function (looping through the JArray and for each JProperty it contain passing it to ProcessJObject function). So now the parsing problem upto any point of nesting of JSON array is solved by the above approach.
Hope it helps.
static void JsonConvert()
{
string sJSON = #"[{""dateNumeric"":1216000000,""hourOfDay"":0,""customerNumber"":12,""storedepartment"":[{""department"":333,""descriptionOfDepartment"":""Department A""},{""department"":111,""descriptionOfDepartment"":""Department B""}]},{""dateNumeric"":1216000000,""hourOfDay"":3,""customerNumber"":3,""storedepartment"":[{""department"":999,""descriptionOfDepartment"":""Department X""},{""department"":888,""descriptionOfDepartment"":""Department Y""}]}]";
var storeDetail = Newtonsoft.Json.JsonConvert.DeserializeObject<List<StoreDetail>>(sJSON);
//iterate your list here
}
public class StoreDetail
{
[JsonProperty("dateNumeric")]
public string DateNumeric { get; set; }
[JsonProperty("hourOfDay")]
public int HourOfDay { get; set; }
[JsonProperty("customerNumber")]
public int CustomerNumber { get; set; }
[JsonProperty("storedepartment")]
public List<StoreDepartment> StoreDepartment { get; set; }
}
public class StoreDepartment
{
[JsonProperty("department")]
public int Department { get; set; }
[JsonProperty("descriptionOfDepartment")]
public string DescriptionOfDepartment { get; set; }
}
string sJSON = #" [{""dateNumeric"":1216000000,""hourOfDay"":0,""customerNumber"":12,""storedepartment"":[{""department"":333,""descriptionOfDepartment"":""Department A""},{""department"":111,""descriptionOfDepartment"":""Department B""}]},{""dateNumeric"":1216000000,""hourOfDay"":3,""customerNumber"":3,""storedepartment"":[{""department"":999,""descriptionOfDepartment"":""Department X""},{""department"":888,""descriptionOfDepartment"":""Department Y""}]}]";
object dJson = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(sJSON);
Console.WriteLine(dJson.ToString());
JArray a = JArray.Parse(sJSON);
foreach (JObject o in a.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
if (p.First.Count() == 0)
{
string name = p.Name;
string value = (string)p.Value;
Console.WriteLine(name + "-- " + value);
}
else
{
string name = p.Name;
Console.WriteLine(name);
string subStr = p.Value.ToString();
JArray aSub = JArray.Parse(subStr);
foreach (JObject oSub in aSub.Children<JObject>())
{
foreach (JProperty pSub in oSub.Properties())
{
string nameSub = pSub.Name;
string valueSub = (string)pSub.Value;
Console.WriteLine("\t" + nameSub + "-- " + valueSub);
}
}
}
}
}
Console.ReadLine();
What's the difference between JsonConvert.DeserializeObject and JObject.Parse? As far as I can tell, both take a string and are in the Json.NET library. What kind of situation would make one more convenient than the other, or is it mainly just preference?
For reference, here's an example of me using both to do exactly the same thing - parse a Json string and return a list of one of the Json attributes.
public ActionResult ReadJson()
{
string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
+"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
"{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";
//Can use either JSONParseObject or JSONParseDynamic here
List<string> counties = JSONParseObject(countiesJson);
JSONParseDynamic(countiesJson);
return View(counties);
}
public List<string> JSONParseObject(string jsonText)
{
JObject jResults = JObject.Parse(jsonText);
List<string> counties = new List<string>();
foreach (var county in jResults["Everything"])
{
counties.Add((string)county["name"]);
}
return counties;
}
public List<string> JSONParseDynamic(string jsonText)
{
dynamic jResults = JsonConvert.DeserializeObject(jsonText);
List<string> counties = new List<string>();
foreach(var county in jResults.Everything)
{
counties.Add((string)county.name);
}
return counties;
}
The LINQ-to-JSON API (JObject, JToken, etc.) exists to allow working with JSON without needing to know its structure ahead of time. You can deserialize any arbitrary JSON using JToken.Parse, then examine and manipulate its contents using other JToken methods. LINQ-to-JSON also works well if you just need one or two values from the JSON (such as the name of a county).
JsonConvert.DeserializeObject, on the other hand, is mainly intended to be used when you DO know the structure of the JSON ahead of time and you want to deserialize into strongly typed classes. For example, here's how you would get the full set of county data from your JSON into a list of County objects.
class Program
{
static void Main(string[] args)
{
string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
+"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
"{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";
foreach (County c in JsonParseCounties(countiesJson))
{
Console.WriteLine(string.Format("{0}, {1} ({2},{3})", c.name,
c.state_abbreviation, c.primary_latitude, c.primary_longitude));
}
}
public static List<County> JsonParseCounties(string jsonText)
{
return JsonConvert.DeserializeObject<RootObject>(jsonText).Counties;
}
}
public class RootObject
{
[JsonProperty("Everything")]
public List<County> Counties { get; set; }
}
public class County
{
public string county_name { get; set; }
public string description { get; set; }
public string feat_class { get; set; }
public string feature_id { get; set; }
public string fips_class { get; set; }
public string fips_county_cd { get; set; }
public string full_county_name { get; set; }
public string link_title { get; set; }
public string url { get; set; }
public string name { get; set; }
public string primary_latitude { get; set; }
public string primary_longitude { get; set; }
public string state_abbreviation { get; set; }
public string state_name { get; set; }
}
Notice that Json.Net uses the type argument given to the JsonConvert.DeserializeObject method to determine what type of object to create.
Of course, if you don't specify a type when you call DeserializeObject, or you use object or dynamic, then Json.Net has no choice but to deserialize into a JObject. (You can see for yourself that your dynamic variable actually holds a JObject by checking jResults.GetType().FullName.) So in that case, there's not much difference between JsonConvert.DeserializeObject and JToken.Parse; either will give you the same result.
JsonConvert.DeserializeObject has one advantage over JObject.Parse:
It is possible to use custom JsonSerializerSettings.
This can be very useful e.g. if you want to control how dates are deserialized.
By default dates are deserialized into DateTime objects.
This means that you may end up with a date with another time zone than the one in the json string.
You can change this behaviour by creating a JsonSerializerSetting and setting
DateParseHandling to DateParseHandling.DateTimeOffset.
An example:
var json = #"{ ""Time"": ""2015-10-28T14:05:22.0091621+00:00""}";
Console.WriteLine(json);
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }
var jObject1 = JObject.Parse(json);
Console.WriteLine(jObject1.ToString());
// Result: { "Time": "2015-10-28T15:05:22.0091621+01:00" }
var jObject2 = Newtonsoft.Json.JsonConvert.DeserializeObject(json,
new Newtonsoft.Json.JsonSerializerSettings
{
DateParseHandling = Newtonsoft.Json.DateParseHandling.DateTimeOffset
});
Console.WriteLine(jObject2.ToString());
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }
For me the key difference I was interested in was Speed.
I made a simple test to find out if it was faster to use JToken.Parse(string) or DeserializeObject<JToken>(string) to create a large amount of JToken and these were the results after 2,000,000 iterations using a sample of real world data
Method
Operating System Ticks
Milliseconds
JsonConvert
86123945
8612ms
JToken
67671724
6767ms
There was some variation between runs but the difference was always large.
Here is the test so you can modify it or run it yourself:
private static string s = #"{'stream':'btcusdt #bookTicker','data':{'u':20430107433,'s':'BTCUSDT','b':'21223.72000000','B':'3.29440000','a':'21223.73000000','A':'2.05450000'}}";
private static Stopwatch sw = new Stopwatch();
private static void Main(string[] args)
{
JToken convert = default;
sw.Restart();
for (int i = 0; i < 2000000; i++)
{
convert = JsonConvert.DeserializeObject<JToken>(s);
}
Console.WriteLine("JsonConvert: " + sw.ElapsedTicks + " [" + sw.ElapsedMilliseconds + "ms]");
convert.ToString();
convert = default;
sw.Restart();
for (int i = 0; i < 2000000; i++)
{
convert = JToken.Parse(s);
}
Console.WriteLine("JToken : " + sw.ElapsedTicks + " [" + sw.ElapsedMilliseconds + "ms]");
convert.ToString();
Console.ReadLine();
}
I knew an advantage that JsonConvert.DeserializeObject can deserialize an Array/List json text directly, but JObject cannot.
Try below sample code:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace NetCoreJsonNETDemo
{
internal class Person
{
[JsonProperty]
internal string Name
{
get;
set;
}
[JsonProperty]
internal int? Age
{
get;
set;
}
}
internal class PersonContainer
{
public List<Person> Persons
{
get;
set;
}
}
class Program
{
static T RecoverPersonsWithJsonConvert<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
static T RecoverPersonsWithJObejct<T>(string json) where T : class
{
try
{
return JObject.Parse(json).ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine("JObject threw an Exception: " + ex.Message);
return null;
}
}
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person()
{
Name = "Jack",
Age = 18
});
persons.Add(new Person()
{
Name = "Sam",
Age = null
});
persons.Add(new Person()
{
Name = "Bob",
Age = 36
});
string json = JsonConvert.SerializeObject(persons, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
List<Person> newPersons = RecoverPersonsWithJsonConvert<List<Person>>(json);
newPersons = RecoverPersonsWithJObejct<List<Person>>(json);//JObject will throw an error, since the json text is an array.
PersonContainer personContainer = new PersonContainer()
{
Persons = persons
};
json = JsonConvert.SerializeObject(personContainer, new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
newPersons = RecoverPersonsWithJObejct<PersonContainer>(json).Persons;
newPersons = null;
newPersons = RecoverPersonsWithJsonConvert<PersonContainer>(json).Persons;
Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
}
Apart from the answers provided here around usage, which are correct as per me :
Jobject.Parse -> when the Json is not strongly Typed or you do not know the structure of Json ahead of time
JsonConvert.DeserializeObject<T> -> When you know which class or type to cast the Json in. T can be a complex class or a simple type
My answer is based on the performance in case where the structure is not known, as given in the OP code, if we benchmark the usage of both methods for performance, it is observed that Jobject.Parse() fares well in terms of allocated memory, please ignore the name of methods, I am first calling the method with 'JsonConvert.DeserializeObject' and then second method is with Jobject.Parse
public class Earthquake
{
public double Magnitude { get; set; }
public string Location { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double depth { get; set; }
public DateTime date { get; set; }
public string EventID { get; set; }
public string URL { get; set; }
public Earthquake()
: this(string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty)
{ }
public Earthquake(string magna, string locate, string lat, string longi, string dept, string dat, string Event, string website)
{
Magnitude = Convert.ToDouble(magna);
Location = locate;
Latitude = Convert.ToDouble(lat);
Longitude = Convert.ToDouble(longi);
depth = Convert.ToDouble(dept);
date = Convert.ToDateTime(dat);
EventID = Event;
URL = website;
}
}
public void GetData()
{
string[] text = File.ReadAllLines(#"Earthquakes.csv");
Earthquake[] data = new Earthquake[1];
foreach (string line in text)
{
string[] myColumns = line.Split(',');
Earthquake[] earth = new Earthquake[myColumns[0], myColumns[1], myColumns[2], myColumns[3], myColumns[4], myColumns[5], myColumns[6], myColumns[7]];
data[i] = earth[i];
i++;
}
}
Ignore commented parts I have those under control. The problem I am having is getting the data from the csv file into the Earthquake Array. I am getting syntax errors, and I know why, it's because the data type isn't correct, but I honestly cannot figure out how to fix it.
Also if you notice I am trying to use bubble sort and since there is no definition for "compare" for double, what do I use instead?
If your reading from CSV file you probably have to remove white space from the split values.
Try adding .Trim() to your column variables
myColumns[0].Trim()
if your looking to sort yor array consider using System.Linq
eg:
var byMag = earthQuakes.OrderBy(e => e.Magnitude);
Looking at your code you posted, GetData() will not work.
Try returning a list or Enumerable
public IEnumerable<Earthquake> GetData(string filename)
{
string[] text = File.ReadAllLines(filename);
foreach (string line in text)
{
string[] myColumns = line.Split(',');
yield return new Earthquake(myColumns[0].Trim(), myColumns[1].Trim(), myColumns[2].Trim(), myColumns[3].Trim(), myColumns[4].Trim(), myColumns[5].Trim(), myColumns[6].Trim(), myColumns[7].Trim());
}
}
Usage:
var earthquakes = GetData(#"Earthquakes.csv");