NewtonSoft JSON Deserialize results in still serialized data - c#

I receive a GET request response from a REST API, in a string. As received, it looks like this:
[
{\"passport_expiration\": \"2019-09-14\", \"first_name\": \"asdfasdf\", \"last_name\": \"asdfasdf\", \"cass_status\": \"APPROVED\", \"notes\": null, \"kcm_status\": \"DENIED\", \"employment_type\": \"flight_deck\", \"employee_id\": \"10556\", \"passport_id\": \"12341234\"},
{\"passport_expiration\": \"2026-01-04\", \"first_name\": \"asdfasdf\", \"last_name\": \"asdfasdf\", \"cass_status\": \"APPROVED\", \"notes\": null, \"kcm_status\": \"DENIED\", \"employment_type\": \"flight_deck\", \"employee_id\": \"10557\", \"passport_id\": \"12341234\"},
{\"passport_expiration\": \"2026-08-31\", \"first_name\": \"asdfasdf\", \"last_name\": \"MC asdfasdf\", \"cass_status\": \"APPROVED\", \"notes\": null, \"kcm_status\": \"DENIED\", \"employment_type\": \"flight_deck\", \"employee_id\": \"10598\", \"passport_id\": \"12341234\"}
]
When I deserialize this into a dynamic:
dynamic dsCrew = JsonConvert.DeserializeObject(responseText);
dsCrew contains this:
{[
{
"passport_expiration": "2026-08-31",
"first_name": "asdfasdf",
"last_name": "MC asdfasdf",
"cass_status": "APPROVED",
"notes": null,
"kcm_status": "DENIED",
"employment_type": "flight_deck",
"employee_id": "10598",
"passport_id": "12341234"
},
{
"passport_expiration": "2026-11-16",
"first_name": "asdfasdf",
"last_name": "BLasdf",
"cass_status": "APPROVED",
"notes": null,
"kcm_status": "DENIED",
"employment_type": "flight_deck",
"employee_id": "14798",
"passport_id": "12341234"
},
{
"passport_expiration": "2025-05-05",
"first_name": "sadfasdf",
"last_name": "asdf",
"cass_status": "APPROVED",
"notes": "",
"kcm_status": "DENIED",
"employment_type": "flight_deck",
"employee_id": "14838",
"passport_id": "12341234"
}
]}
It seems to have simply removed the escape characters, converted some nulls to Empty Strings, and wrapped the whole thing in an additional set of curly braces. It's like it deserialised into just a different serialized format.
In other SO questions, answers have suggested creating a class to deserialise into:
Deserialised_Crew dsCrew = JsonConvert.DeserializeObject<Deserialised_Crew>(responseText);
But when I do that I get an exception:
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'CASS_KCM_Update.Deserialised_Crew' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.
JsonConvert.DeserializeObject() doesn't seem to think the responseText is valid JSON. JSONLint.com says the JSON is valid.
I need a way to reference specific pieces of data:
dsCrew[0].last_name seems to reference the entire text inside the square brackets. And I can't find any way to reference with any more specificity than that. dsCrew[0][1].last_name won't work. dsCrew[0](1).last_name is right out.
I need a way to reference the names and employee_id's in this response. I'm relatively new to JSON.

The first issue is probably just what you see in the debugger. That code should be fine.
Your second problem just involves deserializing to an array, since the JSON object is an array of crew:
Deserialised_Crew[] dsCrew = JsonConvert.DeserializeObject<Deserialised_Crew[]>(responseText);
From there on, your code dsCrew[0].last_name should work as expected.

Related

Json Deserialise not consistent with apparently identical data

I'm deserialising a Newtonsoft JArray to a .NET DataTable using:
DataTable dt = (DataTable)JsonConvert.DeserializeObject(dataSet.ToString(), typeof(DataTable));
Where dataSet is a JArray of the basic array format:
{
"dataset": [
{
"periodDesc": "2020",
"cstCode": "",
"CIFValue": null
},
{
"periodDesc": "2017",
"cstCode": "",
"CIFValue": null
},
...
]
}
I get this dataset from an API call via a JObject and it works fine:
JObject jObject = GetJsonFromWebRequest(url);
JArray jArray = (JArray)jObject["dataset"];
Now to do some testing, I took the json response from the GetJsonFromWebRequest and saved it to a .json file.
I also did the same with the JArray when I encountered problems; Whether I use the whole response and parse to a JObject first, or whether I use the subset JArray, when I load this data from file, it just doesn't work! I get the error:
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'System.Data.DataTable' because the type requires a JSON object (e.g.
{"name":"value"}) to deserialize correctly.\r\nTo fix this error
either change the JSON to a JSON object (e.g. {"name":"value"}) or
change the deserialized type to an array or a type that implements a
collection interface (e.g. ICollection, IList) like List that can
be deserialized from a JSON array. JsonArrayAttribute can also be
added to the type to force it to deserialize from a JSON
array."
I'm assuming this might have something to do with linebreaks or something, or how I've saved it as .JSON instead of .TXT maybe?! But I have no idea what is going on - looking at the objects while debugging they seem absolutely identical and it is successfully parsing the JArray as a JArray - it's just the Deserialize bit that fails.
Any idea what's going on here?!
Here are the contents of the file I'm loading from minus the help URL - the mock response:
{
"validation": {
"status": {
"name": "Ok",
"value": 0,
"category": 0,
"description": "",
"helpUrl": "For more reference visit"
},
"message": null,
"count": {
"value": 5,
"started": "2021-09-15T09:14:05.277794+02:00",
"finished": "2021-09-15T09:14:07.8662927+02:00",
"durationSeconds": 2.5884986999999997
},
"datasetTimer": {
"started": "2021-09-15T09:14:05.277794+02:00",
"finished": "2021-09-15T09:14:15.2487336+02:00",
"durationSeconds": 9.9709396
}
},
"dataset": [
{
"periodDesc": "2017",
"cstCode": "",
"CIFValue": null
},
{
"periodDesc": "2018",
"cstCode": "",
"CIFValue": null
},
{
"periodDesc": "2019",
"cstCode": "",
"CIFValue": null
},
{
"periodDesc": "2020",
"cstCode": "",
"CIFValue": null
}
]
}
Ok, this was something to do with NewtonSoft version incompatibility. I needed to explicitly install NewtonSoft 3.x in my NUnit test project and it works fine.
While the main API project doesn't have this package dependency / reference, it did have a line in the startup:
services.AddControllers().AddNewtonsoftJson();
Which apparently does the same thing?!

Extract schema from JSON data in C#

I have below JSON schema which works ok with JsonConvert.DeserializeObject. I am able to extract schema directly from it but when it comes to JSON Data string, then I am not sure how to extract schema.
{
"fields": [
{
"name": "approved",
"type": "Boolean",
"displayName": "Approved",
"isNullable": true,
"isSearchable": false,
"isFilter": true,
"isInternal": false
}
]
}
In the above JSON, approved is the field name so I am able to extract schema, but I have a JSON data string as below and want to extract schema from it.
{
"skuId": "1",
"balance": [
{
"warehouseId": "1_1",
"warehouseName": "Main Warehouse",
"totalQuantity": 1000001,
"reservedQuantity": 1,
"hasUnlimitedQuantity": true,
"timeToRefill": null,
"dateOfSupplyUtc": null
}
]
}
In the above example JSON data, warehouseid, warehousename, etc., are fieldname and I need to have those in my schema in c#.
Can anyone please suggest?
create a new class, copy your json data string, and in visual studio click edit -> paste special, and it will create classes that you can deserialize to the way you want.
You are missing the closing ']' so that needs to be addressed first.
If you use a dictionary and need to iterate it :
foreach(KeyValuePair<string, string> entry in myDictionary) { // do something with entry.Value or entry.Key }

How do I parse the below dynamic JSON

I have a json which is badly formatted. I want to take out the status and order id from that json. Tried JSON parsing with object, but did not get the result. Please help,
My Json,
{
"formname": [
"Sale_Order_API",
{
"operation": [
"add",
{
"values": {
"Order_ID": "1250",
"Email": "xyz#yws.in",
"Order_Value": "100",
"Restaurant_Name": "HiTech",
"Order_Date": "13-Aug-2019",
},
"status": "Failure, Duplicate values found for
'Order ID'"
}
]
}
]
}
Please help.
This is my first question , please ignore mistakes.
I have tried something like this, But not able to get the inner values
dynamic resultdata = json_serializer.DeserializeObject(postData);
If I understand you correctly, you want to deserialize this JSON. On 'http://json2csharp.com/#' you can generate a C # class from your JSON. Or right by your own. There are plenty of tutorials on the Internet. In case your class, where you give the values of the Json, is called 'JSONResult', you could access the values as follows
var resultdata = JsonConvert.DeserializeObject<JSONResult>(postData);
JSONResult outPut = resultdata;
Console.WriteLine(outPut.formname[0]);
But the longer I look at the format of your JSON, the more confused I get. Where did you get the JSON from? From an API?

How to deserialize json with a blank field?

I have a json string like this:
[{
"_id": "abcd",
"name": "bender rodriguez",
"meta": {
"location": {}
},
dob": ,
}
]
The section after dob blows up:
return new JavaScriptSerializer().Deserialize<T>(json);
The problem is the empty dob. I cannot seem to find any method to handle something like this. Doesn't even seem to be a common problem? I'm not too familiar with deserializing json, what methods can I use to deal with this other than string.replace(": ,"," : null,")?
The JSON deserialiser you're using is fine, the JSON you're trying to deserialice is wrong, it's missing a value, and the initial double quotes for the dob property.
Use JSONLint to validate JSON.
If that JSON is coming from a component you control, then use a JSON serializer to serialize it properly, if not, you can fix that particular problem using this:
string myJson = "[{ \"_id\": \"abcd\", \"name\": \"bender rodriguez\", \"meta\": { \"location\": {} }, dob\": , } ]";
JavaScriptSerializer().Deserialize(myJson.Replace("dob\": ", "\"dob\": \"\""));
But if the data changes and it keeps having an invalid JSON format, there's little you can do about it but asking whoever did that component to send you valid JSON data.

Json Object deserialize to a List<class>

I have a Json string containing arrays and a single key with a value as you can see below.
{
"MSG": "Hallo Stackoverflow!",
"0": {
"ID": "2",
"Subject": "Danish",
"Message": "Message",
"DateEnd": "2016-02-28 00:00:00"
},
"1": {
"ID": "2",
"Subject": "Math",
"Message": "Message",
"DateEnd": "2016-02-29 00:00:00"
}}
I pass this to a JObject to get the MSG value, then remove it from the json. However, when key is gone, the numbers of the array gets deleted and I cannot pass it through my code:
JObject data = JObject.Parse(json);
string MSG = data["MSG"].ToString();
data.Remove("MSG");
List<HomeWork> homework = JsonConvert.DeserializeObject<List<HomeWork>>(json);
I get an error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Memento.HomeWork]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
If I generate it as an array without the key, it works fine.
You are actually trying to deserialize a JSON object rather than a JSON array.
Note that the following would be a JSON array (and you would be able to deserialize it into a List<Homework>):
[{
"ID": "2",
"Subject": "Danish",
"Message": "Message",
"DateEnd": "2016-02-28 00:00:00"
},
{
"ID": "2",
"Subject": "Math",
"Message": "Message",
"DateEnd": "2016-02-29 00:00:00"
}]
In order to deserialize this JSON object, you must use a Dictionary<TKey, TValue> (because you don't know the object's keys beforehand), which in your case is Dictionary<int, Homework>:
Dictionary<int, Homework> homeworks = JsonConvert.DeserializeObject<Dictionary<int, Homework>>(json);
Homework hw = homeworks[0]; //This will be your first homework, the one with ID = 2

Categories