I'm working in ASP.NET and I'm getting this error when trying to serialize a JSON string into a DataTable:
Unexpected JSON token when reading DataTable. Expected StartArray, got
StartObject
I've read other posts that have this same error and it seems like the error normally occurs when the JSON object is invalid. However, I've validated my JSON in JsonLint and it is fine. I'm not constructing the JSON, I'm receiving it from the Paysimple API. I'm also using very similar methods in other parts of my software and it's working fine, so I'm at a loss to explain why the error shows up here.
Any help is greatly appreciated. I don't have a lot of experience working with JSON.
Here is my code:
protected void LoadPaymentSchedule(int customerId)
{
// This method returns an object from Paysimple's API
RecurringPaymentResponse recurringPayment = StudioPaymentAccess.GetStudioPaymentSchedule(customerId);
// Convert the Json response to DataTable
string a = JsonConvert.SerializeObject(recurringPayment);
DataTable tblSchedules = JsonConvert.DeserializeObject<DataTable>(a);//**error occurs here
// Bind to gridview
if (tblSchedules.Rows.Count > 0)
{
grdPaymentSchedules.DataSource = tblSchedules;
grdPaymentSchedules.DataBind();
}
else
{
//No schedules found
}
}
And here is the JSON that is returned by the method above StudioPaymentAccess.GetStudioPaymentSchedule(customerId)
{
"CustomerId": 1149814,
"CustomerFirstName": "Evan W",
"CustomerLastName": "Studio4",
"CustomerCompany": null,
"NextScheduleDate": "2020-11-16T07:00:00Z",
"PauseUntilDate": null,
"FirstPaymentDone": false,
"DateOfLastPaymentMade": "2020-10-16T06:00:00Z",
"TotalAmountPaid": 10.0,
"NumberOfPaymentsMade": 1,
"EndDate": "2021-10-16T06:00:00Z",
"PaymentAmount": 10.0,
"PaymentSubType": "Moto",
"AccountId": 1184647,
"InvoiceNumber": null,
"OrderId": null,
"FirstPaymentAmount": 0.0,
"FirstPaymentDate": null,
"StartDate": "2020-10-16T06:00:00Z",
"ScheduleStatus": "Active",
"ExecutionFrequencyType": "SpecificDayofMonth",
"ExecutionFrequencyParameter": 16,
"Description": " ",
"Id": 181512,
"LastModified": "2020-10-16T07:30:43Z",
"CreatedOn": "2020-10-15T18:11:22Z" }
It looks like in order to deserialize a DataTable, the expected JSON should be an array.
A quick work around do that would be to adjust the serialization so that it writes out an array:
string a = JsonConvert.SerializeObject(new[] { recurringPayment });
Another option would be to bind directly to return model, assuming that DataTable isn't a requirement. For example, see the answer to Binding an ASP.NET GridView Control to a string array.
Are you trying to Deserialize RecurringPaymentResponse Object to System.Data.DataTable?
It will definitely fail if you trying to Deserialize RecurringPaymentResponse Object to System.Data.DataTable. As properties of two class are not same.
You should directly update gridview rows
GridViewRow row = (GridViewRow) GridView1.Rows[0]; //First row
row.Cells[0].Text = recurringPayment.CustomerId;
row.Cells[1].Text = recurringPayment.CustomerFirstName;
row.Cells[2].Text = recurringPayment.CustomerLastName;
//and so on.....
DataTable Expects array as...
{
"data":
[
{"ID":1,"Name":"Simon"},
{"ID":2,"Name":"Alex"}
]
}
I tryed to deserialize but don't ocurred the error to me, the deserialize run successful.
https://i.stack.imgur.com/4tcns.png
Related
My application processes a Json that contains a list of objects. The properties of these objects are not completely known to me.
Example, in the following Json, only property "Id" is known to my application:
{"msgs": [
{
"Id": "Id1",
"A": "AAA"
},
{
"Id": "Id2",
"B": "BBB"
},
{
"Id": "Id3",
"C": "CCC"
}
]}
I want to parse these messages and extract the Id of each message. This has been working fine with the following code:
public class RootElem
{
[BsonElement("msgs")]
public List<JToken> Records { get; set; }
}
then read
var rootElem = JsonConvert.DeserializeObject<RootElem>(JSON_DATA);
Once I have my rootElem, I can iterate over each record in "Records" and extract the Id.
The problem is that sometime, some of the records will contain unexpected characters.
Example:
{
"Id": "Id2",
"B": "THIS CONTAINS UNEXPECTED DOUBLE QUOTE " WHAT SHOULD I DO?"
}
I tried adding error handling settings, but that didn't work:
var rootElem = JsonConvert.DeserializeObject<RootElem>(data, new JsonSerializerSettings
{
Error = HandleDeserializationError
});
private static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
var currentError = errorArgs.ErrorContext.Error.Message;
Console.WriteLine(currentError);
errorArgs.ErrorContext.Handled = true;
}
I want to be able to access the rest of the records in the list, even if one/some of them contain these invalid chars. So I'm ok if "B" value of the 2nd record is return as null, or if the 2nd record is null altogether.
How can I achieve this?
p.s. I'm using Newtonsoft Json but I'm open to using other libraries.
The issue here is that what your application is receiving is not valid JSON, hence the errors you are seeing. The input should be properly escaped prior to being submitted to this method. If this is behind an HTTP API, the appropriate response would be a 400 as the request is not in a valid format. If you really need to work around this it's possible you could implement your own JsonConverter class and decorate the converting class with it, but this may not be possible as the JSON itself is invalid and the JsonReader is going to choke when it hits it.
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?
I have serialized a DataTable with f1 column as byte[]. The column is serialized to Base-64 string as given below:
[
{
"f1": "5hAAJEA=",
"f2": "hi_all",
"id": 1
},
{
"f1": "5hrwJEA=",
"f2": "hi world",
"id": 2
}
]
I used the following code to serialize the datatable with Json.Net:
var json = JsonConvert.SerializeObject(dataTable, settings);
When deserializing the json string to a DataTable, a datatable object is generated with acolumn f1 as string (not byte[]) with the same value of base64 string.
I think that is expected because the datatable is a generic structure without schema.
I know that deserializing using list<Dto> with a property of type byte[] can restore the byte[], but that is not an option because I use the datatable for bulk insert in sql database and deserialization is done at runtime without pre-definition of Dto(POCO) class.
I can create a Typed DataTable from the table definition in the database.
I tried to use ByteJsonConverter ,but it can't help.
You can check the complete c# program online to show the problem:
with a complete trace for json serialization/deserialization process.
Update:
I used TypeNameHandling =TypeNameHandling.Objects, to keep data type in json and get json like:
[
{
"f1": {
"$type": "System.Byte[], mscorlib",
"$value": "5hAAJEA="
},
"f2": "hi all",
"id": 1
},
{
"f1": {
"$type": "System.Byte[], mscorlib",
"$value": "5hrwJEA="
},
"f2": "hi world",
"id": 2
}
]
Now f1 is of type System.Byte[] and it's supposed that DataTableConverter create column of type byte[] not string.
When i try to deserialize, an exception error is fired:
Unexpected JSON token when reading DataTable: StartObject. Path '[0].f1', line 3, position 11
It seems that DataTableConverter can't handle $type/$value pair.
Check the source code
My question:
How to resolve that error for DataTableConverter.
How to deserialize a json string with Base-64 string to byte[] column in the DataTable.
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.
I am trying to Convert Json to DataTable. I found success when converting jsonArray to DataTable. However when converting a json string(below):
var r = {'ASSOCIATION_ID':61.0,'DESCRIPTION':'fssESTf64 - false','ACTIVE':true,'MODEL_TYPE':'0','SEARCH_TYPE':'false','CREATED_BY':'1090323','CREATED_DATE':'2015-09-17T14:41:20','LAST_UPDATED_BY':'1090323','LAST_UPDATED_DATE':'2016-02-26T15:55:54'}
I get an error as {"Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1."}
My code is simple:
DataTable a = JsonConvert.DeserializeObject<DataTable>(r);
Please assist.
Your root JSON container is an object (an unordered collection of comma-separated key/value pairs surrounded by braces - { and }). Json.NET serializes a DataTable as an array of objects (an ordered collection of comma-separated tokens surrounded by square brackets [ and ]), with one array entry for each row, as is shown in Serialize a DataSet. I.e. the following can be deserialized as a data table:
[
{
"ASSOCIATION_ID": 61.0,
"DESCRIPTION": "fssESTf64 - false",
"ACTIVE": true,
"MODEL_TYPE": "0",
"SEARCH_TYPE": "false",
"CREATED_BY": "1090323",
"CREATED_DATE": "2015-09-17T14:41:20",
"LAST_UPDATED_BY": "1090323",
"LAST_UPDATED_DATE": "2016-02-26T15:55:54"
}
]
Thus your JSON cannot be mapped automatically to a DataTable by Json.NET.
If you want, you could deserialize your JSON object as a DataTable with one row. To do that, load it into an intermediate JToken, check if it's an object instead of an array, and if so, wrap it in an array, then deserialize:
var token = JToken.Parse(r);
if (token.Type == JTokenType.Object)
token = new JArray(token);
var a = token.ToObject<DataTable>();