JSON trouble; deserialising to a datatable - c#

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": n‌​ull,
"type": null,
"Category": null,
"IsHierarchy": false,
"IntervalsEnabled": true,
"IsRe‌​altimeCompatible": 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

Related

How do I parse this json string

I want to get the Cape URL but I'm having some trouble accessing It.
{
"timestamp": <java time in ms>,
"profileId": "<profile uuid>",
"profileName": "<player name>",
"signatureRequired": true, // Only present if ?unsigned=false is appended to url
"textures": {
"SKIN": {
"url": "<player skin URL>"
},
"CAPE": {
"url": "<player cape URL>"
}
}
}
I have tried multiple json methods but I can't figure out how to do it
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
dynamic dobj = jsonSerializer.Deserialize<dynamic>(thestring);
object result = dobj["textures"][0]["CAPE"][0]["url"];
It seem you are trying to treat the objects in your parsed json as some sort of array.
In both places where you've used [0], it is being done on an object. This would look for a key with the name 0 which doesn't exist.
Instead, you should just use the json keys directly.
Your final code should look something like this:
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
dynamic dobj = jsonSerializer.Deserialize<dynamic>(thestring);
object result = dobj["textures"]["CAPE"]["url"];

Unexpected JSON token when reading DataTable

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;
}

JSON JObject.Parse modifies json string

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>>();

C# and json data parsing

I have a problem on data parsing, I am using C# in Visual Studios and I need a parsing algorithm for my json file. This is the structure:
{
"objects": {
"minecraft/sounds/mob/stray/death2.ogg": {
"hash": "d48940aeab2d4068bd157e6810406c882503a813",
"size": 18817
},
"minecraft/sounds/mob/husk/step4.ogg": {
"hash": "70a1c99c314a134027988106a3b61b15389d5f2f",
"size": 9398
},
"minecraft/sounds/entity/rabbit/attack2.ogg": {
"hash": "4b90ff3a9b1486642bc0f15da0045d83a91df82e",
"size
I want to pull "minecraft/sounds/mob/stray/death2.ogg" and "hash" the data.
My C# code:
HttpWebRequest reqobje = WebRequest.Create(assetsurl) as HttpWebRequest;
using (HttpWebResponse response = reqobje.GetResponse() as HttpWebResponse)
{
StreamReader objejsonsr = new StreamReader(objectjson);
jsonVerisi = objejsonsr.ReadToEnd();
}
parser = JObject.Parse(jsonVerisi);
JToken job = parser["objects"];
Since you're using json.net, you can deserialize the string into any object you need. The sample below is an anonymous type with dictionary so you can use the dynamic keys that are coming back:
var result = JsonConvert.DeserializeAnonymousType(jsonVerisi, new { objects =
new Dictionary<string, Dictionary<string, string>>() });
var objects = result.objects; // key/value;
This is one way you can use it (maybe even to map to your own model instead of anonymous types to make it easier to work with):
var objects = result.objects
.Select(m => new
{
Path = m.Key,
Hash = m.Value["hash"],
Size = int.TryParse(m.Value["size"], out var value) ? value : 0,
}).ToList();
var path = objects[0].Path; // Get the path of the first object

How to read JSON response in c#

I am using thirparty service to give me coordinates, below is the response I want to read this using c# .net in some kind of object so that I can use the information but confused how to achieve this..
{"found": 1, "bounds": [[52.45401, -1.96211], [52.45401, -1.96211]], "features": [{"id": 65140,"centroid": {"type":"POINT","coordinates":[52.45401, -1.96211]},"bounds": [[52.45401, -1.96211], [52.45401, -1.96211]],"properties": {"name": "B17 0SL"},"type": "Feature"}], "type": "FeatureCollection", "crs": {"type": "EPSG", "properties": {"code": 4326, "coordinate_order": [0, 1]}}}
Thanks
have a look at Newtonsoft.Json its a package that will deserialize the Json into a class for you.
but you will need to create the class structure you want to use.
Use a json parser like DataContractJsonSerializer or JavaScriptSerializer
For your case for ex., using Json.Net & dynamic keyword, you can write
dynamic jObj = JsonConvert.DeserializeObject(jsonstr);
Console.WriteLine(jObj.found);
Console.WriteLine(jObj.features[0].bounds[0][0]);
You can use JsonTextReader. The following code segment may be useful, if you are not using JSON.NET
jsonString = {"found": 1, "bounds": [[52.45401, -1.96211], [52.45401, -1.96211]], "features": [{"id": 65140,"centroid": {"type":"POINT","coordinates":[52.45401, -1.96211]},"bounds": [[52.45401, -1.96211], [52.45401, -1.96211]],"properties": {"name": "B17 0SL"},"type": "Feature"}], "type": "FeatureCollection", "crs": {"type": "EPSG", "properties": {"code": 4326, "coordinate_order": [0, 1]}}};
JsonTextReader reader = new JsonTextReader(new StringReader(jsonString));
while (reader.Read())
{
if (reader.Value != null)
{
// Read Json values here
// reader.Path -> Gives you the key part.
// reader.Value.ToString() -> Gives you the value part
}
}
You can read the JSON like this:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
JArray array = new JArray();
using (var twitpicResponse = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(twitpicResponse.GetResponseStream()))
{
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
JObject joResponse = JObject.Parse(objText);
JObject result = (JObject)joResponse["result"];
array = (JArray)result["Detail"];
string statu = array[0]["dlrStat"].ToString();
}
}
You can use JSON.NET

Categories

Resources