JSON not deserializing correctly with large object - c#

I am trying to deserialize a JSON string and for some reason it will not work.
string json_string = "{'CartID':{'ID':253419,'AuthenticatedKey':223239},'CustomerID':null,'PurchaseItems':null,'TenderInformation':null,'ModifyCartItems':null,'AdditionalCartInformation':{'ServiceInformation':{'ServiceInformationItem':[{'ServiceID':243401}]}}}";
modifyCartReq = JsonConvert.DeserializeObject<ModifyCartReq>(json_string);
I have also tried the following
string json_string = "{'CartID':{'ID':253419,'AuthenticatedKey':223239},'CustomerID':null,'PurchaseItems':null,'TenderInformation':null,'ModifyCartItems':null,'AdditionalCartInformation':{'ServiceInformation':{'ServiceInformationItem':[{'ServiceID':243401}]}}}";
modifyCartReq = JsonSerializer.Deserialize<ModifyCartReq>(json_string);
I get the same error below
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'ExampleType' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'AdditionalCartInformation.ServiceInformation.ServiceInformationItem', line 1, position 213.
From my attempts at solving this It feels like some syntax issue is ultimately the cause of this.

you have to fix json_string
{
"CartID": {
"ID": 253419,
"AuthenticatedKey": 223239
},
"CustomerID": null,
"PurchaseItems": null,
"TenderInformation": null,
"ModifyCartItems": null,
"AdditionalCartInformation": {
"ServiceInformation": {
"ServiceInformationItem": [{
"ServiceID": 243401
}]
}
}
}
try this
modifyCartReq = JsonSerializer.Deserialize<Root>(json_string);
and use this classes
public class CartID
{
public int ID { get; set; }
public int AuthenticatedKey { get; set; }
}
public class ServiceInformationItem
{
public int ServiceID { get; set; }
}
public class ServiceInformation
{
public List<ServiceInformationItem> ServiceInformationItem { get; set; }
}
public class AdditionalCartInformation
{
public ServiceInformation ServiceInformation { get; set; }
}
public class Root
{
public CartID CartID { get; set; }
public object CustomerID { get; set; }
public object PurchaseItems { get; set; }
public object TenderInformation { get; set; }
public object ModifyCartItems { get; set; }
public AdditionalCartInformation AdditionalCartInformation { get; set; }
}
just replace objects with your real types.

Related

Multiple employees Json gives Deserializing error

I am reading 2 REST APIs using Httpclient in C#. The APIs return following employee data in JSON format:
1st API
{
"status": "OK",
"content": {
"empid1": 89900,
"empid2": 45550,
"empid3": 22350}
}
2nd API
{
"status": "OK",
"content": {
"empid1": "grade1",
"empid1": "grade2",
"empid1": "grade2"}}
Classes defined and code used is as follows:
public class content
{
public string empid { get; set; } // e.g. empid3
public double salary { get; set; } // e.g. 89900
public string grade { get; set; } // e.g. Grade1
}
public sealed class WrapperEmployees
{
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("data")]
public List<content> empdata { get; set; } = new List<data>();
}
To deserialize, used this-
WrapperEmployees nj = JsonConvert.DeserializeObject<WrapperEmployees>(response);
But, last line gives error on deserialization:
Cannot deserialize current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CsharpSample.App_Code.Employee]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'content.emp1', line 4, position 18.
Is my class structure incorrect?
My ultimate aim is to fetch common data from both APIs against employees.
Option 1: use specific classes for each json deserialization:
class EmployeesSalaries {
public string Status { get; set; }
public Dictionary<string, int> content { get; set; };
}
class EmployeesGrades {
public string Status { get; set; }
public Dictionary<string, string> content { get; set; };
}
Option 2: deserialize to common class, but you will get 'good' content values only if they are int/string. If they will be objects - you will have JObjects as values.
class EmployeesData {
public string Status { get; set; }
public Dictionary<string, object> content { get; set; };
}

How to fix 'Cannot deserialize the current JSON array into type 'passages' because requires a JSON object (e.g. {"name":"value"}) to deserialize

I am trying to read and access a large JSON file from local directory using newtonsoft.json in c# but always gave me the error. I created two classes for accessing it.
This is my example JSON data:
{
"passages": [
{
"passage_text": "xxxxxxx",
"url": "xxxxx",
}
]
"answer":"xxxxxx",
"query_id":"Xxxxx"
}
here is the code I have tried:
public class collection
{
public passages passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
public class passages
{
public String url { get; set; }
public String passage_text { get; set; }
}
Here is the part I tried to read and access to JSON file:
String jsonPath = #"C:\Users\admin\Desktop\647\project\collection\sample_collection.json" ;
var serializer = new JsonSerializer();
StreamReader sr = new StreamReader(jsonPath);
JsonTextReader reader = new JsonTextReader(sr);
reader.SupportMultipleContent = true;
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
collection c = serializer.Deserialize<collection>(reader);
Console.WriteLine(c.passages.url);
}
}
And it gave me this error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'LuceneIndexApplication.passages' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To 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.
Path '[0].passages', line 1, position 15.'
you are trying to map passages to from an array into a list.
so all that you should need to change is:
public class collection
{
public passages passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
should be
public class collection
{
public List<passages> passages { get; set; }
public String answers { get; set; }
public String query_id { get; set; }
}
note the List in the latter.

Unusual Deserialization Error from JSON to C#

.Net Fiddle 1
I have a JOSN received from external API as follows
[{
"assignedto": "MAIN STAFF",
"createduser": "API-71",
"departmentid": "1",
"observations": [{
"abnormalflag": "abnormal",
"analytename": "HGB A1C",
"value": "5"
}],
"pages": [],
"priority": "2",
"status": "REVIEW"
}]
I did a Paste Special in Visual Studio and got following classes
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string assignedto { get; set; }
public string createduser { get; set; }
public string departmentid { get; set; }
public Observation[] observations { get; set; }
public object[] pages { get; set; }
public string priority { get; set; }
public string status { get; set; }
}
public class Observation
{
public string abnormalflag { get; set; }
public string analytename { get; set; }
public string value { get; set; }
}
When I do a deserialization, I am getting following error
Run-time exception (line 24): Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Rootobject' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To 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.
Path '', line 1, position 1.
C# Code
public static void Main(string[] args)
{
var json = #"[{
""assignedto"": ""MAIN ST (HUB) STAFF"",
""createduser"": ""API-7127"",
""departmentid"": ""1"",
""observations"": [{
""abnormalflag"": ""abnormal"",
""analytename"": ""HGB A1C"",
""value"": ""5""
}],
""pages"": [],
""priority"": ""2"",
""status"": ""REVIEW""
}]";
Rootobject resultObj = JToken.Parse(json).ToObject<Rootobject>();
}
I referred similar questions like Create a strongly typed c# object from json object with ID as the name - but that is a different issue.
Any idea how to fix this? Also what is the better way to generate C# classes from JSON?
Note: I also tried with class I got from http://json2csharp.com/. That also faield - Fidlle 2
I would use Newtonsoft / Json convert and change this:
Rootobject resultObj = JToken.Parse(json).ToObject<Rootobject>();
to:
using Newtonsoft.Json;
-- snip --
var resultObj = JsonConvert.DeserializeObject<List<Class1>>(json);
Console.WriteLine(resultObj.Count); // 1
Class1 result = resultObj[0];
Console.WriteLine(result.assignedto); // "MAIN ST (HUB) STAFF"
This will give you a collection of RootObject
As #JeffMeracdo states above - you are providing a collection of object and trying to parse as though it is a single object
As #JeffMeracdo states above, try this:
List<Example> resultObj = JsonConvert.DeserializeObject<List<Example>>(json);
Following using statement and package along with Newtonsoft.Json Nuget package:
using Newtonsoft.Json;
Classes:
public class Observation
{
public string abnormalflag { get; set; }
public string analytename { get; set; }
public string value { get; set; }
}
public class Example
{
public string assignedto { get; set; }
public string createduser { get; set; }
public string departmentid { get; set; }
public List<Observation> observations { get; set; }
public List<object> pages { get; set; }
public string priority { get; set; }
public string status { get; set; }
}

Can't implement Iterator design pattern after JsonConvert when trying to Deserialize json

I have the following Object that matches the pattern of a JSON object i get from one REST request I send:
public class MyObject
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}
public class DisplayValue
{
public Id DisplayId { get; set; }
}
public class Id
{
public List<string> IdToName { get; set; }
}
this object match to the response I get and the next code is working with the upper implementation of MyObject (I'm using C#'s RestSharp):
var response = client.Execute(request);
result = JsonConvert.DeserializeObject<MyObject>(response.Content);
Now I would like to implement the Iterator design pattern on MyObject since MyObject.rows is the only field I actually use.
So I've changed MyObject class to the following
public class MyObject : IEnumerable<List<string>
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
}
public IEnumerator<List<string>> GetEnumerator()
{
foreach (List<string> row in rows)
{
yield return row;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class DisplayValue
{
public Id DisplayId { get; set; }
}
public class Id
{
public List<string> IdToName { get; set; }
}
But when I try to JSONConvert I get the following exception:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'MyObject' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly. To fix this error either change the JSON to a JSON array
(e.g. [1,2,3]) or change the deserialized type so that it is a normal
.NET type (e.g. not a primitive type like integer, not a collection
type like an array or List) that can be deserialized from a JSON
object. JsonObjectAttribute can also be added to the type to force it
to deserialize from a JSON object.
Any idea to why is this happening?
The problem is that Json.NET will try to serialize any POCO that implements IEnumerable<T> for some T as a JSON array rather than a JSON object, as is documented here. Since your JSON is presumably not an array, you receive the exception you are seeing.
Since you don't want your MyObject serialized as an array, you can force Json.NET to (de)serialize it as an object instead by marking it with [JsonObject]:
[JsonObject]
public class MyObject : IEnumerable<List<string>>
{
public List<string> columns { get; set; }
public List<List<string>> rows { get; set; }
public DisplayValue displayValue { get; set; }
public string currency { get; set; }
public object alert { get; set; }
// Implementation of IEnumerable<List<string>>...
}
See JsonObjectAttribute force object serialization.

Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[obJson]'

I am trying to Deserialize (using Newtonsoft) JSON and convert to List in c#. It is throwing me error " Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[obJson]'."
Here is my JSON string:
string webContent = "{\"searchResults\": [{\"gefId\":0,\"resultNumber\":1,\"distance\":4.2839,\"sourceName\":\"MQA.MQ_34172_HD\",\"name\":\"USER_DEFINED\"},{\"gefId\":0,\"resultNumber\":1,\"distance\":4.2839,\"sourceName\":\"MQA.MQ_34172_HD\",\"name\":\"USER_DEFINED\"}]}";
Conversion, this line is throwing error:
List<obJson> result = JsonConvert.DeserializeObject<List<obJson>>(webContent);
My custom classes:
public class SearchResults
{
public int gefId { get; set; }
public int resultNumber { get; set; }
public decimal distance { get; set; }
public string sourceName { get; set; }
public string name { get; set; }
}
public class obJson
{
public SearchResults SearchResults { get; set; }
}
Since your json is an object whose searchResults member contains an array, change your obJson as below
public class obJson
{
public List<SearchResults> searchResults { get; set; }
}
and deserialize as
obJson result = JsonConvert.DeserializeObject<obJson>(webContent);
The problem is with your model or conversely with data you are sending. You are receiving an array and hoping to deserialize it into plain object. You can change your model like
public class obJson
{
public SearchResults[] SearchResults { get; set; }
}
and your result will be deserialized just fine.
your json is not valid.
Parse error on line 1:
{ \"searchResults\": [
-----^
Expecting 'STRING', '}'
http://jsonlint.com/

Categories