Deserializing JSON Object into C# list - c#

I have some JSON that I want to deserilize into a list<> object.
I am using JsonConvert by Newtonsoft and I have setup my public classes to support the list. These are as follows.
public class NewDocumentObject
{
public int ContractId { get; set; }
public int FolderId { get; set; }
public string CreatedAt { get; set; }
public string CreatedBy { get; set; }
public string TemplateReference { get; set; }
public bool IsTest { get; set; }
public bool IsExplicitName { get; set; }
public object Requester { get; set; }
public object ExternalReference { get; set; }
public object ExternalLabel { get; set; }
public string Status { get; set; }
public string StatusLabel { get; set; }
public int Share { get; set; }
public int EffectiveRight { get; set; }
public string Name { get; set; }
public object ModifiedAt { get; set; }
public object ModifiedBy { get; set; }
public object ModifiedById { get; set; }
public object ProfileReference { get; set; }
public object ESignatureId { get; set; }
public List<object> Documents { get; set; }
public object Folder { get; set; }
public object Session { get; set; }
public string ESignatureStatus { get; set; }
public List<object> Alerts { get; set; }
public List<Link> Links { get; set; }
}
public class Link
{
public string rel { get; set; }
public string method { get; set; }
public string href { get; set; }
}
The JSON is as follows.
{
"ContractId": 103,
"FolderId": 6,
"CreatedAt": "2016-02-18T11:30:17.293",
"CreatedBy": "SMTC",
"TemplateReference": "Non Disclosure Agreement",
"IsTest": false,
"IsExplicitName": false,
"Requester": null,
"ExternalReference": null,
"ExternalLabel": null,
"Status": "Incomplete",
"StatusLabel": "Incomplete",
"Share": 0,
"EffectiveRight": 3,
"Name": "Non Disclosure Agreement",
"ModifiedAt": null,
"ModifiedBy": null,
"ModifiedById": null,
"ProfileReference": null,
"ESignatureId": null,
"Documents": [],
"Folder": null,
"Session": null,
"ESignatureStatus": "",
"Alerts": [],
"Links": [{
"rel": "questionnaire",
"method": "get",
"href": "http://srv-dev-29/api/contracts/103/questionnaire/pages/1?navigate=first"
}, {
"rel": "answers",
"method": "get",
"href": "http://srv-dev-29/api/contracts/103/answers"
}, {
"rel": "documents",
"method": "get",
"href": "http://srv-dev-29/api/contracts/103/documents"
}, {
"rel": "template",
"method": "get",
"href": "http://srv-dev-29/api/templates/Non Disclosure Agreement"
}, {
"rel": "folder",
"method": "get",
"href": "http://srv-dev-29/api/folders/6"
}, {
"rel": "self",
"method": "get",
"href": "http://srv-dev-29/api/contracts/103"
}]}
To deserialize the JSON I have the following line.
List<NewDocumentObject> newDoc = JsonConvert.DeserializeObject<List<NewDocumentObject>>(response.Content.ReadAsStringAsync().Result);
This is where it's falling over. The JsonConvertor is throwing and exception.
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ContractExpressAPITest.Form1+NewDocumentObject]' 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 'ContractId', line 1, position 14.
I suspect this is because it's not able to handle the List items in the JSON.
Anyone able to help??
Thanks

Copy your JSON to the clipboard and then if your are using Visual Studio in the "Edit> Paste Special> Paste JSON as classes." and then do the same

You are trying to deserialize into a List
List<NewDocumentObject> newDoc = JsonConvert.DeserializeObject<List<NewDocumentObject>>(response.Content.ReadAsStringAsync().Result);
But your JSON string contains an object {} only.
Change your JSON input to [{...}]
Or change your deserialize call to only one object.

You cannot serialize or deserialize a List of <object>. You must use a strongly typed class.

Related

Use Json file as db

I am starting c# and I was asked to create a small Api using a given Json file as DB.
My json file looks like:
{"Items": [
{
"id": 1,
"name": "Apple",
"price": 12.50,
"image": "some url",
"description": "Some text",
"tags": [ "fruit", "red" ],
"category": "fruit"
},
]}
I created a model:
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Image { get; set; }
public string Description { get; set; }
public List<Tags> Tags { get; set; }
public string Category { get; set; }
}
public class Tags
{
public string Tag { get; set; }
}
And my controller looks like:
[ApiController]
[Route("api/[controller]")]
public class ProductController : Controller
{
[HttpGet]
public IEnumerable<Product> Get()
{
StreamReader r = new StreamReader("./items.json");
string jsonString = r.ReadToEnd();
List<Product> productsList = JsonConvert.DeserializeObject<List<Product>>(jsonString);
return productsList;
}
}
The error I get:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Kata.Product]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
As I am new to c#, I am having trouble to find out how to simply return what I have in my Json file. At some point I was able to return the list by changing the json file(not the greatest idea) but all the items were null.
Thank you
You have a bug in your json classes. You can't use a special class for the tags, try to replace it by string array or list. The same about items. You deserialized the whole Root object, items just a property of this object. So since you don't need the whole object but just list of items, you have to select only them.
var jsonDeserialized= JsonConvert.DeserializeObject<Root> (jsonString);
List<Product> productsList = jsonDeserialized.Items ;
classes
public class Product
{
public int id { get; set; }
public string name { get; set; }
public double price { get; set; }
public string image { get; set; }
public string description { get; set; }
public List<string> tags { get; set; }
public string category { get; set; }
}
public class Root
{
public List<Product> Items { get; set; }
}
and fix json
{
"Items": [{
"id": 1,
"name": "Apple",
"price": 12.50,
"image": "some url",
"description": "Some text",
"tags": ["fruit", "red"],
"category": "fruit"
}]
}

Extract few values from JSON Array

The problem I am facing is that I am getting 0's for the values I ask for in the JSON.
I recently asked a question here about getting specific values from a JSON array response that come from an API.
Now I have a new JSON response from a different route and in there I want one values and its called EntityId its places in a block of Entity See the code for more details, I would like to grab that from this response and place them in a list or Array because it tells me who submitted the assignment in D2L.
UPDATE- After getting comments from a user I used JSON to C# tool to create the full class with all the values but I still get the values as 0,0,0,0.
Right now I am getting 0,0,0,0 values and not getting the actual values if it's possible I would like to grab the whole block on Entity.
JSON
[
{
"Entity": {
"DisplayName": "FullName",
"EntityId": 123,
"EntityType": "User",
"Active": true
},
"Status": 1,
"Feedback": null,
"Submissions": [
{
"Id": 27,
"SubmittedBy": {
"Identifier": "123",
"DisplayName": "FullName"
},
"SubmissionDate": "2019-08-01T15:25:04.130Z",
"Comment": {
"Text": "",
"Html": ""
},
"Files": [
{
"IsRead": false,
"IsFlagged": false,
"IsDeleted": false,
"FileId": 1245,
"FileName": "1.2.10.png",
"Size": 144407
},
{
"IsRead": false,
"IsFlagged": false,
"IsDeleted": false,
"FileId": 292,
"FileName": "1.3.8.png",
"Size": 127869
}
]
}
],
"CompletionDate": "2019-08-01T15:25:04.130Z"
},
{
"Entity": {
"DisplayName": "FullName",
"EntityId": 123,
"EntityType": "User",
"Active": true
},
"Status": 1,
"Feedback": null,
"Submissions": [
{
"Id": 41,
"SubmittedBy": {
"Identifier": "123",
"DisplayName": "FullName"
},
"SubmissionDate": "2019-08-03T03:31:43.807Z",
"Comment": {
"Text": " \nAlex",
"Html": "<p></p>\n<p>Alex</p>"
},
"Files": [
{
"IsRead": false,
"IsFlagged": false,
"IsDeleted": false,
"FileId": 313,
"FileName": "Capture 1.2.10 Questions.PNG",
"Size": 97722
}
]
}
],
"CompletionDate": "2019-08-03T03:31:43.807Z"
}
]
Classes:
public class Entity
{
public string DisplayName { get; set; }
public int EntityId { get; set; }
public string EntityType { get; set; }
public bool Active { get; set; }
}
public class SubmittedBy
{
public string Identifier { get; set; }
public string DisplayName { get; set; }
}
public class Comment
{
public string Text { get; set; }
public string Html { get; set; }
}
public class File
{
public bool IsRead { get; set; }
public bool IsFlagged { get; set; }
public bool IsDeleted { get; set; }
public int FileId { get; set; }
public string FileName { get; set; }
public int Size { get; set; }
}
public class Submission
{
public int Id { get; set; }
public SubmittedBy SubmittedBy { get; set; }
public DateTime SubmissionDate { get; set; }
public Comment Comment { get; set; }
public IList<File> Files { get; set; }
}
public class Example
{
public Entity Entity { get; set; }
public int Status { get; set; }
public object Feedback { get; set; }
public IList<Submission> Submissions { get; set; }
public DateTime CompletionDate { get; set; }
}
Code:
var request = new RestRequest(string.Format(Link));
request.Method = Method.GET;
authenticator.Authenticate(client, request);
var response = client.Execute(request);
var thisasa = JsonConvert.DeserializeObject<List<Example>>
(response.Content).Select(
o => o.Identifier).ToList();
The Example data model shown in your question already can be used to successfully deserialize the JSON shown. All that's left is to pick out the Entity.EntityId property via a Select:
var thisasa = JsonConvert.DeserializeObject<List<Example>>(response.Content)
.Select(o => o.Entity.EntityId)
.ToList();
Demo fiddle #1 here.
Incidentally, if you only need Entity.EntityId you could simplify your data model as follows:
public class Entity
{
public int EntityId { get; set; }
}
public class Example
{
public Entity Entity { get; set; }
}
Demo fiddle #2 here.
(As an aside, since your Example class corresponds to the documented object Dropbox.EntityDropbox, you might want to rename your type to EntityDropbox for clarity.)

Deserialize JSON not working with newtonsoft.json

I have a json String as below, which i am using the deserialize into my class objects but I can't, here is my json.:
{
"TraceId": "24bf6a01-5d8f-4959-9173-20600a04b738",
"TransactionId": "AFC48AE50A076477C3E069296AC3F884",
"ResponseTime": "1672",
"DistanceUnits": "MI",
"CurrencyType": "GBP",
"xmlns:air": "http://www.travelport.com/schema/air_v42_0",
"air:FlightDetailsList": {
"air:FlightDetails": [
{
"Key": "hx5kk+3R2BKAuFzqAAAAAA==",
"Origin": "DXB",
"Destination": "LHE",
"DepartureTime": "2017-12-10T13:55:00.000+04:00",
"ArrivalTime": "2017-12-10T17:55:00.000+05:00",
"FlightTime": "180",
"TravelTime": "180",
"Equipment": "320",
"OriginTerminal": "1",
"DestinationTerminal": "M"
},
{
"Key": "hx5kk+3R2BKAwFzqAAAAAA==",
"Origin": "LHE",
"Destination": "DEL",
"DepartureTime": "2017-12-20T12:15:00.000+05:00",
"ArrivalTime": "2017-12-20T14:10:00.000+05:30",
"FlightTime": "85",
"TravelTime": "690",
"Equipment": "ATR",
"OriginTerminal": "M",
"DestinationTerminal": "3"
},
{
"Key": "hx5kk+3R2BKAyFzqAAAAAA==",
"Origin": "DEL",
"Destination": "DXB",
"DepartureTime": "2017-12-20T20:25:00.000+05:30",
"ArrivalTime": "2017-12-20T22:45:00.000+04:00",
"FlightTime": "230",
"TravelTime": "690",
"Equipment": "788",
"OriginTerminal": "3",
"DestinationTerminal": "1"
}
]
}
}
So I want to convert into my class LowFareSearchRsp and its FlightDetails class is also shown below:
public class LowFareSearchRsp
{
public string TraceId { get; set; }
public string TransactionId { get; set; }
public string ResponseTime { get; set; }
public string DistanceUnits { get; set; }
public string CurrencyType { get; set; }
public string air { get; set; }
public FlightDetailsList FlightDetailsList { get; set; }
}
public class FlightDetailsList
{
public List<FlightDetails> FlightDetails { get; set; }
}
public class FlightDetails
{
public string Key { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public DateTime Departure { get; set; }
public DateTime ArrivalTime { get; set; }
public string FlightTime { get; set; }
public string TravelTime { get; set; }
public string Equipment { get; set; }
public string OriginTerminal { get; set; }
public string DestinationTerminal { get; set; }
}
and I'm using the NewtonSoft library to deserialize that json to my class object but getting the following error:
{"Cannot deserialize the current JSON object (e.g.
{\"name\":\"value\"}) into type
'System.Collections.Generic.List`1[ParseSoapEnveloperReqRes.LowFareSearchRsp]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.\r\nTo 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.\r\nPath 'TraceId', line 2, position
12."}
Here is my code to deserialize the json string:
var LowFareSearchRsps = JsonConvert.DeserializeObject<List<LowFareSearchRsp>>(jsonString);
I'he had searched the whole internet, but can't find the solution of this. Kindly Help. Thanks.
Your JSON string represent an object not an array change deserilize code to be as below:
var LowFareSearchRsps = JsonConvert.DeserializeObject<LowFareSearchRsp>(jsonString);
Your JSON does not represent a List<LowFareSearchRsp> but a LowFareSearchRsp.

Deserialize Json to C# object with array of arrays

Hello I have serious issues with populating my JSON file to C# object, because JSON contains "array of arrays of arrays". I need to create class with all the arrays to be able load the files there after deserialize, but i have no idea how to create structure like that.
JSON file:
{
"status": true,
"result": [
{
"ID": "1",
"UserID": "1001",
"web_id": "2753",
"certificate_id": "31",
"domain": "testsomething.com",
"status": "ssl_uninstalling",
"updated_at": "2017-02-15 15:08:04",
"IP": "xx.x.xxx.xxx",
"OS_version": "CentOS release 4.8"
},
{
"ID": "2",
"UserID": "1001",
"web_id": "2753",
"certificate_id": "31",
"domain": "admin.testsomething.com",
"status": "ssl_uninstalling",
"updated_at": "2017-02-13 14:19:45",
"IP": "xx.x.xxx.xxx",
"OS_version": "CentOS release 4.8"
},
{
"ID": "3",
"UserID": "1001",
"web_id": "2753",
"certificate_id": "31",
"domain": "www.testsomething16.com",
"status": "ssl_uninstalling",
"updated_at": "2017-02-16 16:22:40",
"IP": "xx.x.xxx.xxx",
"OS_version": "CentOS release 4.8"
},
{
"ID": "4",
"UserID": "1001",
"web_id": "2753",
"certificate_id": "31",
"domain": "blog.testsomething.com",
"status": "ssl_uninstalling",
"updated_at": "2017-02-16 16:22:40",
"IP": "xx.x.xxx.xxx",
"OS_version": "CentOS release 4.8"
}
],
"errors": []
}
The structure for your json might look like
public class Result
{
[JsonProperty("ID")]
public string ID { get; set; }
[JsonProperty("UserID")]
public string UserID { get; set; }
[JsonProperty("web_id")]
public string web_id { get; set; }
[JsonProperty("certificate_id")]
public string certificate_id { get; set; }
[JsonProperty("domain")]
public string domain { get; set; }
[JsonProperty("status")]
public string status { get; set; }
[JsonProperty("updated_at")]
public string updated_at { get; set; }
[JsonProperty("IP")]
public string IP { get; set; }
[JsonProperty("OS_version")]
public string OS_version { get; set; }
}
public class Rootobject
{
[JsonProperty("status")]
public bool status { get; set; }
[JsonProperty("result")]
public List<Result> result { get; set; }
[JsonProperty("errors")]
public List<object> errors { get; set; }
}
You can use Visual Studio to create classes for you out of JSON.
Copy your JSON in the clipboard. that means just CTRL + C and then go to Visual Studio Edit -> Paste Special -> Paste JSON As Classes
Another way out to create class sturcture for your JSON could be you can go to json2csharp: generate c# classes from json and create the classes.
I think you can create a model like below:
public class Example
{
public bool Status { get; set; }
public ResultModel ResultModel { get; set; }
public bool Error { get; set; }
public Example()
{
ResultModel = new ResultModel();
}
}
public class ResultModel
{
public int ID { get; set; }
public int UserId { get; set; }
public int WebId { get; set; }
}

JSON Deserialization Error in C#

I want to Deserialize a JSON object to C# but I'm getting this exception:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'FYP___Task_1.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.
I've tried to get this error solved by different solutions I found on StackOverflow but no one worked.
The JSON I'm using is as follows:
[
{
"rating_count": 158271,
"genres": [
"Action",
"Crime",
"Thriller"
],
"rated": "PG-13",
"language": [
"English",
"French",
"Mandarin"
],
"rating": 6.7,
"country": [
"France",
"USA"
],
"release_date": 20021011,
"title": "Transporter\n \"The Transporter\"",
"year": 2002,
"filming_locations": "Avenue de Saissy, Cannes, Alpes-Maritimes, France",
"imdb_id": "tt0293662",
"directors": [
"Corey Yuen"
],
"writers": [
"Luc Besson",
"Robert Mark Kamen"
],
"actors": [
"Jason Statham",
"Qi Shu",
"Matt Schulze",
"François Berléand",
"Ric Young",
"Doug Rand",
"Didier Saint Melin",
"Tonio Descanvelle",
"Laurent Desponds",
"Matthieu Albertini",
"Vincent Nemeth",
"Jean-Yves Bilien",
"Jean-Marie Paris",
"Adrian Dearnell",
"Alfred Lot"
],
"also_known_as": [
"Transporter"
],
"poster": {
"imdb": "http://ia.media-imdb.com/images/M/MV5BMTk2NDc2MDAxN15BMl5BanBnXkFtZTYwNDc1NDY2._V1_SY317_CR3,0,214,317_.jpg",
"cover": "http://imdb-poster.b0.upaiyun.com/000/293/662.jpg!cover?_upt=cd37cf0e1385015165"
},
"runtime": [
"92 min"
],
"type": "M",
"imdb_url": "http://www.imdb.com/title/tt0293662/"
}
]
The classes I'm using:
public class Poster
{
public string imdb { get; set; }
public string cover { get; set; }
}
public class RootObject
{
public int rating_count { get; set; }
public List<string> genres { get; set; }
public string rated { get; set; }
public List<string> language { get; set; }
public double rating { get; set; }
public List<string> country { get; set; }
public int release_date { get; set; }
public string title { get; set; }
public int year { get; set; }
public string filming_locations { get; set; }
public string imdb_id { get; set; }
public List<string> directors { get; set; }
public List<string> writers { get; set; }
public List<string> actors { get; set; }
public List<string> also_known_as { get; set; }
public Poster poster { get; set; }
public List<string> runtime { get; set; }
public string type { get; set; }
public string imdb_url { get; set; }
}
Your JSON object has the structure [ {..} ] which means it is a list of objects. In your case, your list has only one object, but it is still a list. What you are trying to do is turn the list into an object, so you get an exception.
The solution is either to change your JSON to {..} (i.e. remove the square brackets) OR deserialize the JSON into an array of RootObject and then just read the first one, for example:
RootObject[] myArray = json.Deserialize<RootObject[]>("json goes here");
RootObject firstObject = myArray[0];
We can try the below option also.
var root = response1.Content.ReadAsAsync<RootObject>().Result;
GridView1.DataSource = root.items;

Categories

Resources