I have the following json string:
{
"Orders": [{
"SubOrderNo": "0582715",
"ItemNo": "20415541",
"ItemType": "ART",
"ItemName": "Fish",
"TemplateName": "TP1234",
"ObjectType": "MPP",
"ObjectId": "PE1234",
"SalesStartDate": "2018-08-01",
"InfoText": "Some dummy text. This till be replaced later with some awesome text instead. Happy Fish!",
"Attachment": null,
"TemplateImage": null,
"ApprovedBy": "Me",
"ExpectedDeliveryDate": "2017-10-20",
"Context": null,
"TemplateDescription": null,
"ColorStatus": 0,
"spArticles": []
}],
"JsonOrders": null
}
I have validate this on json lint, so it's valid json.
I have the following code:
public static DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
When I run this, I get the error:
Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1.
Anyone who can tell why I can't convert my json to datatable?
Use this one, I hope it will work.
//require .net Framework 4.5 above.
public static DataTable Tabulate(string jsonContent)
{
var jsonLinq = JObject.Parse(jsonContent);
// Find the first array using Linq
var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
var trgArray = new JArray();
foreach (JObject row in srcArray.Children<JObject>())
{
var cleanRow = new JObject();
foreach (JProperty column in row.Properties())
{
// Only include JValue types
if (column.Value is JValue)
{
cleanRow.Add(column.Name, column.Value);
}
}
trgArray.Add(cleanRow);
}
return JsonConvert.DeserializeObject<DataTable>(trgArray.ToString());
}
If you don't want to map your object you can try this way:
string json = File.ReadAllText("bryan.json");
dynamic result = JsonConvert.DeserializeObject(json);
Console.WriteLine(result.Orders[0].ObjectId);
This will create an object without giving a class, which will dinamically allocate the properties in the exactly same way as your js object
You need to deserialize your json string into object first and then use that object to convert into data table
public static DataTable jsonStringToTable(string jsonContent)
{
dynamic jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonContent);
DataTable dt = JsonConvert.DeserializeObject<DataTable>(Convert.ToString(jsonObject.Orders));
return dt;
}
Related
Below is my Requirement-
Actual JSON=
{
"page":2,
"per_page":6,
"total":12,
"total_pages":2
}
I want to make it as below-
[
{
"page":2,
"per_page":6,
"total":12,
"total_pages":2
}
]
It would be great help if someone can provide the best logic to do this in C# (RestSharp)
Basically you can store your json data inside the list.
var json = new
{
name = "john doe",
age = 20
};
var list = new List<dynamic>();
list.Add(json);
Later on, when you serialize your list. It will look like this:
[{"name":"john doe","age":20}]
Hopefully it helps.
Create an empty array and then push json object into that array.
Example :
var obj = { "name":"test", "email":"test#test.com" };
var list = [];
list.push(obj);
Result :
list = [{ "name":"test", "email":"test#test.com" }];
You can use below code, this is working one.
var obj = new { name = "test", email = "test#test.com" };
var list = new List<dynamic>();
list.Add(obj);
I have a JSON string like below:
{
"MetaData": {
"ResourcesUsed": 1
},
"Result": [
{
"locations": [
{
"country": "Papua New Guinea",
"city": "Jacquinot Bay",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-08T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
},{
"country": "Papua New Guinea2",
"city": "Jacquinot Bay2",
"locTypeAttributes": {
"localDate": "2018-10-08T04:21:00-07:00",
"utcDate": "2018-10-02T04:21:00-07:00",
},
"point": {
"coordinates": [
151.52,
-5.6
],
"type": "Point"
}
}
]
}
]
}
I converted it to a JSON object using Newtonsoft. What I want to do is to sort the locations array(s) inside the Result array by the utcDate field nested in each locations item. I found the following thread: C# Sort JSON string keys. However, I could not still implement it since I have arrays inside my object, while that question deals purely with sorting objects inside objects alphabetically by property name.
Here is a piece of code that I wrote so far:
public string GenerateJson()
{
var model = (JObject)JsonConvert.DeserializeObject(data);
Sort(model);
}
private void Sort(JObject jObj)
{
var props = jObj["Result"][0]["locations"].ToList();
foreach (var prop in props)
{
prop.Remove();
}
foreach (var prop in props.OrderBy(p => p.Name))
{
jObj.Add(prop);
if (prop.Value is JObject)
Sort((JObject)prop.Value);
if (prop.Value is JArray)
{
Int32 iCount = prop.Value.Count();
for (Int32 iIterator = 0; iIterator < iCount; iIterator++)
if (prop.Value[iIterator] is JObject)
Sort((JObject)prop.Value[iIterator]);
}
}
}
You can sort each individual "Result[*].locations" array using LINQ as follows:
// Load the JSON without parsing or converting any dates.
var model = JsonConvert.DeserializeObject<JObject>(data, new JsonSerializerSettings{ DateParseHandling = DateParseHandling.None });
// Construct a serializer that converts all DateTime values to UTC
var serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings{ DateTimeZoneHandling = DateTimeZoneHandling.Utc });
foreach (var locations in model.SelectTokens("Result[*].locations").OfType<JArray>())
{
// Then sort the locations by utcDate converting the value to UTC at this time.
var query = from location in locations
let utcDate = location.SelectToken("locTypeAttributes.utcDate").ToObject<DateTime>(serializer)
orderby utcDate
select location;
locations.ReplaceAll(query.ToList());
}
Notes:
The JSON is initially loaded using DateParseHandling.None to prevent the "localDate" and "utcDate" strings from being prematurely interpreted as DateTime objects with a uniform DateTime.Kind.
(For a discussion of how Json.NET interprets strings that look like dates, see Serializing Dates in JSON.)
We then iterate through all "locations" arrays using SelectTokens("Result[*].locations") where [*] is the JSONPath wildcard character, selecting all entries in the "Results" array.
We then order each "locations" array by deserializing the nested locTypeAttributes.utcDate to a UTC date, then ordering using LINQ.
Finally the array is updated using JArray.ReplaceAll().
If any locTypeAttributes.utcDate property is missing, an exception will be thrown. You could instead deserialize to DateTime? if that is a possibility.
Working sample .Net fiddle here.
I have got incomming Json in format:
{
"Type": "value",
"Name": "MeteoStation",
"UniqueAdress": "2C:3A:E8:0F:10:76",
"valuesList": [{
"Value": 23.00,
"Unit": "C",
"Type": "temperature",
"SourceUniqAdress": "2C:3A:E8:0F:10:76",
"TimeCaptured": "2018-03-26T09:36:13.200Z"
}]
}
In my program, I want to create object IValuePacket that is one value in list of values.
JObject jobject = JObject.Parse(incomingJson);
var settings = new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var incommingMessage = JsonConvert.DeserializeObject<MessageEncapsulation>(incomingJson);
string Type = incommingMessage.Type;
string name = incommingMessage.Name;
if (string.IsNullOrWhiteSpace(name))
name = "no name";
if (Type.ToLower().Equals("value")) {
var values = JsonConvert.DeserializeObject<List<IValuePacket>>(jobject["valuesList"].ToString());
}
Everything works fine untill I recieved exact this json as mention above.
JObject.Parse modifies value TimeCaptured and jobject looks like:
{
"Type": "value",
"Name": "Meteostation",
"UniqueAdress": "2C:3A:E8:0F:10:76",
"valuesList": [{
"Value": 23.00,
"Unit": "C",
"Type": "temperature",
"SourceUniqAdress": "2C:3A:E8:0F:10:76",
"TimeCaptured": "2018-03-26T09:36:13.2Z"
}]}
Thats not so much difference, but DateTime.ParseExact(value, "yyyy-MM-ddThh:mm:ss.fffZ", System.Globalization.CultureInfo.InvariantCulture); cannot parse new value. Actually, I am sending 201 ms instead of 200 ms. It works, but I want to have good time for future reasons.
Is there any way how to avoid changing in Json during parsing?
It does not really modify your string, it just parses your date string into DateTime object when you call JObject.Parse. If you do this:
var obj = JObject.Parse(json);
var values = (JArray) obj["valuesList"];
var time = (JValue) values[0]["TimeCaptured"];
Console.WriteLine(time.Value.GetType());
You notice that time.Value is of type DateTime. Then you do this:
JsonConvert.DeserializeObject<List<IValuePacket>>(jobject["valuesList"].ToString());
By doing that you convert valueList back to json, but now TimeCaptured is DateTime and not a string, so that DateTime object is converted to json string using whatever date time format is used by JSON.NET by default.
You can avoid parsing strings that look like dates to .NET DateTime objects by parsing json to JObject like this:
JObject obj;
using (var reader = new JsonTextReader(new StringReader(json))) {
// DateParseHandling.None is what you need
reader.DateParseHandling = DateParseHandling.None;
obj = JObject.Load(reader);
}
Then type of TimeCaptured will be string, as you expect.
Side note: there is no need to convert JToken back to string and then call JsonConvert.Deserialize on that string. Instead, do this:
var values = obj["valuesList"].ToObject<List<IValuePacket>>();
I have these data in thhe codebehind and tried to pass it to javascript function in various formats: array of list, json string but no way to get data by a javascript var object.
Here is the last format of data in the code behind:
List<string>[] array2 = new List<string>[listLenght];
array2.Initialize();
for (int ii = 0; ii < listLenght; ii++)
{
array2[ii] = new List<string>();
array2[ii].Add(Convert.ToString(dt.Rows[ii][5]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][9]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][10]));
array2[ii].Add(Convert.ToString(dt.Rows[ii][11]));
}
Then tried to call javascript in this way:
string createArrayScript = string.Format("var array2 = [{0},{1},{2},{3}];",
string.Join(",",",",",", array2));
But returns an error:
FormatException was unhandled by user code.The index (zero based) must be greater than or equal to zero and less than the size of the list of topics
This is the call to the function:
Page.ClientScript.RegisterStartupScript(this.GetType(), "registerPoiArray", createArrayScript, true);
Here is the javascript var format:
var markers = Poi;
var markers = [
{
"title": "via Andria, Roma",
"lat": 41.8902643,
"lng": 12.6638589,
"description": "fdsad"
},
{
"title": "via canosa, Roma",
"lat": 41.8838417,
"lng": 12.5438227,
"description": "fdsad"
},
{
"title": "via taranto, Milano",
"lat": 45.4383343,
"lng": 9.1505354,
"description": "fdsad"
},
{
"title": "via barletta, Roma",
"lat": 41.9102707,
"lng": 12.4580826,
"description": "fdsad"
}];
I can not pass this array in javascript.
You can create a custom class to represent the Datatable. Say if your data table has four columns, create a custom class which has 4 fields in it. Loop through the data table and convert it in to an array of objects of the custom class type.
Finally you can serialize the array into json using the following code.
JavaScriptSerializer js = new JavaScriptSerializer();
js.Serialize(data);
where data is the array of objects.
This is the technique i used..
Data table cannot be serialized easily to JSON directly. refer What's the best way to jSON serialize a .NET DataTable in WCF?
You have to escape (double up) the curly brace when using String.Format if you want it to spit out the actual curly brace character.
Example:
string createArrayScript =
string.Format("var array2 = [{{0}},{{1}},{{2}},{{3}}];",
...
Try to use
System.Web.Helpers.Json.Encode
And change the structure you are getting.
List<object> toEncode=new List<object>();
foreach (DataRow dr in dt.Rows){
Dictionary<string,string> element=new Dictionary<string,string>();
element.Add("title",dr["title"] as string);
//repeat for all neaded colums
toEncode.Add(element);
}
string jsonString=Json.Encode(toEncode);
I created a gist when I put the solution.
I hope this works for you...
Regards,
Just use NewtonSoft Json and call:
var JsonString = JsonConvert.SerializeObject(NameofDT, Formatting.Indented)
I am trying to load JSON into a SQL database using JSON.net.
I've had no issues with other JSON responses however the following format doesn't seem to deserialise correctly.
{"Report":["2012m01d01","2012m01d02","2012w01","2012m01","2012m01d03","2012m01d04","2012m01d05","2012m01d06","2012m01d07","2012m01d08"],
"Realtime":null}
Could anybody provide some insight into why this would be? I'm using the following code to deserialise with.
public void Deserialize(String jsonText, ref DataTable dt)
{
JsonSerializer json = new JsonSerializer();
json.NullValueHandling = NullValueHandling.Ignore;
json.ObjectCreationHandling = ObjectCreationHandling.Replace;
json.MissingMemberHandling = MissingMemberHandling.Ignore;
json.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
StringReader sr = new StringReader(jsonText);
JsonTextReader reader = new JsonTextReader(sr);
dt = (DataTable)json.Deserialize(reader, typeof(DataTable));
reader.Close();
}
Any ideas on what the best approach to solving this would be? This works fine with other JSON responses!
Thanks in advance
JSON is able to hold hirarchial information, that does not translate into a single datatable, but rather into several using a dataset and table relationships.
I put your json in http://jsonlint.com validator and formatter
you say this deserializes with no problems
{
"accountID": 1,
"profileID": null,
"name": "Pages",
"ID": "18d039ae0360",
"language": null,
"type": null,
"Category": null,
"IsHierarchy": false,
"IntervalsEnabled": true,
"IsRealtimeCompatible": true,
"properties": null
}
this is a single object
but this doesn't deserialize properly.
{
"Report": [
"2012m01d01",
"2012m01d02",
"2012w01",
"2012m01",
"2012m01d03",
"2012m01d04",
"2012m01d05",
"2012m01d06",
"2012m01d07",
"2012m01d08"
],
"Realtime": null
}
Actually your problem is data handling not serializion
the first is a single object and can be deserialized into a DataTable
and the other is an object that holds a reference to a list of report objects.
therefore you need to manually write a converter from your object to two dataTables
this code works, and i'm sure you can create a conversion function for your two tables
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Error,
NullValueHandling = NullValueHandling.Include
};
JsonSerializer json = JsonSerializer.Create(settings);
json.Error += (x, y) =>
{
var s = y.ErrorContext;
var t = y.CurrentObject;
};
StringReader sr = new StringReader(jsonString);
JsonTextReader reader = new JsonTextReader(sr);
var o = json.Deserialize<ClsReport>(reader);
string sf = o.ReportItems[2];
Hope this helps