Trouble Deserializing JSON - c#

I am attempting to get students from an api and display their information but am having some trouble deserializing some json that I am retrieving. I am using c#
Here is what is being retrieved:
[
{
"firstName": "John",
"lastName: "Smith",
"id": "122386144",
"schoolYear": "Sophmore",
"Links": [
{
"url": "https://github.com/johnsmith",
"comments": "Click to see some of my projects!"
}
],
"GPA": "3.6"
},
{
"firstName": "Jane",
"lastName: "Doe",
"id": "45624523",
"schoolYear": "Junior",
"Links": [
{
"url": "https://linkedin.com/janedoe",
"comments": "Follow me on LinkedIn"
}
],
"GPA": "3.8"
}
]
Here is what I have for my class:
public class Student
{
public string firstName { get; set; }
public string lastName { get; set; }
public int id { get; set; }
public string schoolYear { get; set; }
public string[] Links { get; set; }
}
public class Links
{
public string url { get; set; }
public string comments { get; set; }
}
And Finally my code deserializing the json. I cannot provide the actual url here so the below baseUrl is just a placeholder for this post:
string baseUrl = "https://CodeUniversity.com/"
List<Student> studentList = new List<Student>();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseUrl);
client.DefaultRequestHeaders.Clear();
client.DeafultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/CS/students");
if (response.IsSuccessStatusCode)
{
var studentResponse = response.Content.ReadAsStringAsync().Result;
studentList = JsonConvert.DeserializeObject<List<Student>(studentResponse);
}
}
When this code runs I receive the following error:
The model item passed into the dictionary is of type
'Newtonsoft.Json.JsonReaderException', but this dictionary requires a
model item of type
'System.Collections.Generic.IEnumerable`1[University.Models.Student]'.
Thanks in advance for the help.

It seems like your Links property of class Student should be type of Links instead of string[].
I would also suggest renaming the Links class to Link

change public string[] Links for public Link[] Links { get; set; }
use this site for convert your json to c# class
your models class
public partial class Student
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("schoolYear")]
public string SchoolYear { get; set; }
[JsonProperty("Links")]
public Link[] Links { get; set; }
[JsonProperty("GPA")]
public string Gpa { get; set; }
}
public partial class Link
{
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("comments")]
public string Comments { get; set; }
}
and deserialize
var c = JsonConvert.DeserializeObject<Student[]>(studentResponse);
check example here

there is a bug in json, add " to lastName before : . Also fix Links property and add GPA property
public class Student
{
public string firstName { get; set; }
public string lastName { get; set; }
public int id { get; set; }
public string schoolYear { get; set; }
public double GPA { get; set; }
public List<Link> Links { get; set; }
}
public class Link
{
public string url { get; set; }
public string comments { get; set; }
}

Related

Xamarin Forms - JSON - Getting Nested Values

Sorry for the basic question, please don't flame me.
But how do I get a nested value form a JSON package? I was able to get the first field but the nested values baffle me.
Here's the json response:
{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "27",
"short_name" : "27",
"types" : [ "street_number" ]
},
]
"formatted_address" : "xxxxx",
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
"name" : "27 Percy St",
"place_id" : "xxxxx",
"reference" : "xxxxx",
"types" : [ "premise" ],
"url" : "https://maps.google.com/?q=xxxxx&ftid=0x6b12bc036a9c581d:0x661b35b7a051a51",
"utc_offset" : 600,
"vicinity" : "xxxx"
},
"status" : "OK"
I want to get the formatted_address but I can only seem to get the status part.
Here's my code:
string GooglePlaceAPIKey = "xxxx";
string SelectedPlaceID = googleplace.PlaceID;
string GooglePlaceDetailAPI = "https://maps.googleapis.com/maps/api/place/details/json?key=" + GooglePlaceAPIKey + "&place_id=" + SelectedPlaceID;
Console.WriteLine(GooglePlaceDetailAPI);
var client = new HttpClient();
var uri = GooglePlaceDetailAPI;
var response_status = await client.GetAsync(uri);
var response_package = await response_status.Content.ReadAsStringAsync();
Root results = JsonConvert.DeserializeObject<Root>(response_package);
Console.WriteLine(results.status);
And here's my class:
public class Root
{
public List<Prediction> predictions { get; set; }
public string status { get; set; }
// Google Places Details
public List<object> html_attributions { get; set; }
public Result results { get; set; }
}
public class Result
{
public List<AddressComponent> address_components { get; set; }
public string formatted_address { get; set; }
public string icon { get; set; }
public string name { get; set; }
public string place_id { get; set; }
public string reference { get; set; }
public List<string> types { get; set; }
public string url { get; set; }
public int utc_offset { get; set; }
public string vicinity { get; set; }
}
I also tried changing the deserialiser to another class so I can pull out the formatted_address but no values seem to be stored in that variable.
Result results = JsonConvert.DeserializeObject<Result>(response_package);
Any advice would be appreciated.
The code is basically correct, you just need to get the address_components from the Root object again.
Root results = JsonConvert.DeserializeObject<Root >(response_package);
var address_components = results.result.address_components;
the model:
public class Root
{
public string status { get; set; }
// Google Places Details
public List<object> html_attributions { get; set; }
public Result result { get; set; } //notice here you should use "result" the same as the key in your json string.
}
public class Result
{
public List<AddressComponent> address_components { get; set; }
public string formatted_address { get; set; }
public string icon { get; set; }
public string name { get; set; }
public string place_id { get; set; }
public string reference { get; set; }
public List<string> types { get; set; }
public string url { get; set; }
public int utc_offset { get; set; }
public string vicinity { get; set; }
}
public class AddressComponent
{
public string long_name { get; set; }
public string short_name { get; set; }
public List<string> types { get; set; }
}

How to map json key to a class property

I have a json response like below
{
"Robert": [
{
"id": "123",
"class": "7th",
"lastname": "johnson"
}
],
"William": [
{
"id": "124",
"class": "7th",
"lastname": "parker"
}
]
}
i want to map it to c# class.
Using online converter i get below structure
public class Robert {
public string id { get; set; }
public string class { get; set; }
public string lastname { get; set; }
}
public class William {
public string id { get; set; }
public string class { get; set; }
public string lastname { get; set; }
}
public class Application {
public IList<Robert> Robert { get; set; }
public IList<William> William { get; set; }
}
instead i would like to map the student name as one of the class property say .. "Name"
public class Student{
public string Name{ get; set; } //Robert is mapped to this
public string id { get; set; }
public string class { get; set; }
public string lastname { get; set; }
}
How can i do this ?
You can read above JSON like this
var responseObject = JsonConvert.DeserializeObject<JObject>(responseStream); //Deserialized JSON to type of JObject
var robert = responseObject["Robert"].ToObject<Student>();
your student class should be like this
public class Student{
public string id { get; set; }
public string class { get; set; }
public string lastname { get; set; }
}
with this, you can read the id, class, lastname of Robert.
just an option to read JSON responses like yours.
class Program
{
public class Student
{
public string Name { get; set; } //Robert is mapped to this
public string id { get; set; }
[JsonProperty("class")]
public string _class { get; set; }
public string lastname { get; set; }
}
static void Main(string[] args)
{
var responseStream = #"{""Robert"": [{""id"": ""123"",""class"": ""7th"",""lastname"": ""johnson""}],""William"": [{""id"": ""123"",""class"": ""7th"",""lastname"": ""johnson""}]}";
var responseObject = JsonConvert.DeserializeObject<JObject>(responseStream); //Deserialized JSON to type of JObject
var list = responseObject.Properties();
var students = new List<Student>();
foreach (var item in list)
{
var s = responseObject[item.Name].ToObject<List<Student>>();
s.ForEach(x => x.Name = item.Name);
students.AddRange(s);
}
}
}
Deserialize the json to Dictionary<string, List<Student>> and use Linq to convert to the desired object
var strJSON = File.ReadAllText("json1.json");
var objStudents = JsonConvert.DeserializeObject<Dictionary<string, List<Student>>>(strJSON);
var result = objStudents.Select(x => new Student
{
Name = x.Key,
id = x.Value[0].id,
studentclass = x.Value[0].studentclass,
lastname = x.Value[0].lastname,
}).ToList();

Deserialize complex JSON at c#

I get this object from API
{
"addedAt": 1573172075745,
"vid": 12590024,
"canonical-vid": 12590024,
"merged-vids": [],
"portal-id": 62515,
"is-contact": true,
"profile-token": "AO_T-mOW3t21rXoDQIhBpPulGUoTyxQKLbBxaHrS2P3MsXjF4qFJ9BIvIgkVDpeha5P3GHujF8FOP-0XFRndATAU_YogQKRBTDddOFx8s_DITNLUrnfU07QCwW61HUPygEAyDeNG6N8d",
"profile-url": "https://app.hubspot.com/contacts/62515/contact/12590024",
"properties": {
"firstname": {
"value": "Matt"
},
"lastmodifieddate": {
"value": "1573172075745"
},
"company": {
"value": "HubSpot"
},
"lastname": {
"value": "Schnitt"
}
}
}
and try to fill this model
class UserProperties
{
public string firstname { get; set; }
public DateTime lastmodifieddate { get; set; }
public string company { get; set; }
public string lastname { get; set; }
}
class UserForDeserialize
{
public int vid { get; set; }
public List<UserProperties> properties { get; set; }
}
with this code
class ApiControl
{
public void GetAllUsers()
{
using (var client = new WebClient())
{
client.Headers.Add("Content-Type:application/json");
client.Headers.Add("Accept:application/json");
var result = client.DownloadString("https://api.hubapi.com/contacts/v1/lists/recently_updated/contacts/recent?hapikey=demo&count=2");
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
dynamic dobj = jsonSerializer.Deserialize<dynamic>(result);
var obf = dobj["contacts"];
foreach (var item in obf)
{
var exampleModel = jsonSerializer.Deserialize<UserForDeserialize>(json);
}
Console.Read();
}
}
}
Id filled good but list of Properties have all null properties.
Maybe it's because of "value" field inside each property but I can't find good solution for this.
What can I try to deserialize JSON?
Your class should be like this.
public class Root
{
public long addedAt { get; set; }
public int vid { get; set; }
public int canonicalvid { get; set; }
public object[] mergedvids { get; set; }
public int portalid { get; set; }
public bool iscontact { get; set; }
public string profiletoken { get; set; }
public string profileurl { get; set; }
public Properties properties { get; set; }
}
public class Properties
{
public Firstname firstname { get; set; }
public Lastmodifieddate lastmodifieddate { get; set; }
public Company company { get; set; }
public Lastname lastname { get; set; }
}
public class Firstname
{
public string value { get; set; }
}
public class Lastmodifieddate
{
public string value { get; set; }
}
public class Company
{
public string value { get; set; }
}
public class Lastname
{
public string value { get; set; }
}
and then deserialise using this.
JavaScriptSerializer js = new JavaScriptSerializer();
Root rootObject = js.Deserialize<Root>(result );
Looks like the model generated from json is incorrect. I have used json2csharp to convert your json and the model looked like below
public class Firstname
{
public string value { get; set; }
}
public class Lastmodifieddate
{
public string value { get; set; }
}
public class Company
{
public string value { get; set; }
}
public class Lastname
{
public string value { get; set; }
}
public class Properties
{
public Firstname firstname { get; set; }
public Lastmodifieddate lastmodifieddate { get; set; }
public Company company { get; set; }
public Lastname lastname { get; set; }
}
public class UserForDeserialize
{
public int vid { get; set; }
public Properties properties { get; set; }
}
After this, I am able to read the properties
using (StreamReader r = new StreamReader(filename))
{
string json = r.ReadToEnd();
var obj = JsonConvert.DeserializeObject<UserForDeserialize>(json);
Console.WriteLine(obj.properties.firstname);
}
Change the type of your properties in 'UserProperties' for another class which contains:
public string value { get; set; }
Because you're missing that property inside your UserProperties object, I think that's the principal problem you're dealing with.

Unable to Parsing nested Json file in C#

I have Json format response from a API call and I want to map the data from the response to each varibales.
Json format
{
"success": true,
"data": {
"students": [
{
"Admission_date": "2018-05-01",
"Name": "Sree",
"Branch": "Electronics",
"Semester": "2",
"HOD": "Mahesh",
},
{
"Admission_date": "2018-05-01",
"Name": "Naresh",
"Branch": "Electronics",
"Semester": "2",
"HOD": "Mahesh",
}
],
"remaining": 0
}
}
I have tried to parse the JSON response and then to load the value through for each. But I'm not able to achieve the solution.
JObject jsonparsing1 = JObject.Parse(str4); //str4;- Json value
var token1 = (JArray)jsonparsing1.SelectToken("data");
var token2 = (JArray)jsonparsing1.SelectToken("data[0]Students");
JArray abc = JsonConvert.DeserializeObject<JArray>(token2.ToString());
foreach (var test in abc)
{
String Admission_date=test["Admission_date"];
String Name=test["Name"];
String Branch=test["Branch"];
String Semester=test["Semester"];
String HOD=test["HOD"];
String remaining=test["remaining"];
}
Expected result
String Admission_date=Admission_date
String Name=Name
String Branch=Branch
String Semester=Semester
String HOD=HOD
String remaining=remaining
Could anyone please help me on this?
I think you can use this sample:
public class JsonData
{
public bool success { get; set; }
public Data data { get; set; }
}
public class Data
{
public Data()
{
this.students = new List<Student>();
}
public List<Student> students { get; set; }
public int remaining { get; set; }
}
public class Student
{
public string Admission_date { get; set; }
public string Name { get; set; }
public string Branch { get; set; }
public string Semester { get; set; }
public string HOD { get; set; }
}
And then:
JsonData abc = JsonConvert.DeserializeObject<JsonData>(token2.ToString());
I will do this way!
public class Student
{
public string Admission_date { get; set; }
public string Name { get; set; }
public string Branch { get; set; }
public string Semester { get; set; }
public string HOD { get; set; }
}
public class Data
{
public List<Student> students { get; set; }
public int remaining { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public Data data { get; set; }
}
and in C# Code Just use only below line:
var obj = JsonConvert.DeserializeObject<RootObject>("{ \"success\": true,\"data\": {\"students\": [{ \"Admission_date\": \"2018-05-01\",\"Name\": \"Sree\",\"Branch\":\"Electronics\",\"Semester\": \"2\",\"HOD\": \"Mahesh\",}],\"remaining\": 0}}");
use
foreach(var item in obj.data.students)
{
// Access Admission_date etc.
string name = item.Name;
}
dotnetfiddle

Retrieve the values from json string

I have json string. I want to retrieve the contact from json string. Following json contains array of contacts. here is my json string.
{
   "contacts": {
      "contact": [
         {
            "isConnection": false,
            "id": 33554611,
            "fields": [
               {
                  "id": 33554748,
                  "type": "name",
                  "value": {
                     "givenName": "Jhon",
                     "middleName": "",
                     "familyName": "Scot",
                     "prefix": "",
                     "suffix": "",
                     "givenNameSound": "",
                     "familyNameSound": ""
                  },
                  "editedBy": "OWNER",
                  "flags": [],
                  "categories": [],
                  "updated": "2012-12-23T07:40:23Z",
                  "created": "2012-12-23T07:40:23Z",
               },
               {
                  "id": 33554749,
                  "type": "email",
                  "value": "someone#example.com",
                  "editedBy": "OWNER",
                  "flags": [],
                  "categories": [],
                  "updated": "2012-12-23T07:40:23Z",
                  "created": "2012-12-23T07:40:23Z",
               }
            ]
         }
}
}
Here I want to retrieves the values of givenName,familyName,email. How can I retrieve the values of these from json string.
Note: there are array of contact in json. I have posted only one contact from this json.
I tried something like this. But not worked.
JObject json = JObject.Parse(returnStr);
JArray fields = (JArray)json["contacts"]["contact"]["fields"][0];
JArray FValues = (JArray)json["contact"]["fields"]["value"];
I tried this
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public List<object> flags { get; set; }
public List<object> categories { get; set; }
public string updated { get; set; }
public string created { get; set; }
public string uri { get; set; }
public bool? isConnection { get; set; }
}
public class contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
public List<object> categories { get; set; }
public int error { get; set; }
public int restoredId { get; set; }
public string created { get; set; }
public string updated { get; set; }
public string uri { get; set; }
}
public class Contacts
{
public List<contact> contact { get; set; }
public int count { get; set; }
public int start { get; set; }
public int total { get; set; }
public string uri { get; set; }
public bool cache { get; set; }
}
public class RootObject
{
public Contacts contacts { get; set; }
}
and
JavaScriptSerializer serializer1 = new JavaScriptSerializer();
RootObject obje = serializer1.Deserialize<RootObject>(returnStr);
But it is giving me 0 value in obje.
First make sure your Json is in valid format using jsonlint
Then generate class base on it using json2csharp
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public List<object> flags { get; set; }
public List<object> categories { get; set; }
public string updated { get; set; }
public string created { get; set; }
}
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
}
public class Contacts
{
public List<Contact> contact { get; set; }
}
public class RootObject
{
public Contacts contacts { get; set; }
}
Use Newtonsoft JSON to deserialize your Json into object(s) then you may simply access its properties value.
JsonConvert.DeserializeObject<RootObject>(string json);
Class for json object (generated with http://jsonutils.com/ after correcting some syntax error):
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public IList<object> flags { get; set; }
public IList<object> categories { get; set; }
public DateTime updated { get; set; }
public DateTime created { get; set; }
}
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public IList<Field> fields { get; set; }
}
public class Contacts
{
public IList<Contact> contact { get; set; }
}
public class Example
{
public Contacts contacts { get; set; }
}
Deserialization (you will probably need to add a reference to System.Web.Extensions):
System.Web.Script.Serialization.JavaScriptSerializer deSer = new System.Web.Script.Serialization.JavaScriptSerializer();
JSonPrintSettingsToXml.Input.Example deserializedJSON = deSer.Deserialize<JSonPrintSettingsToXml.Input.Example>(yourJSON);
Here is the corrected JSON
{
"contacts": {
"contact": [
{
"isConnection": false,
"id": 33554611,
"fields": [
{
"id": 33554748,
"type": "name",
"value": {
"givenName": "Jhon",
"middleName": "",
"familyName": "Scot",
"prefix": "",
"suffix": "",
"givenNameSound": "",
"familyNameSound": ""
},
"editedBy": "OWNER",
"flags": [],
"categories": [],
"updated": "2012-12-23T07:40:23Z",
"created": "2012-12-23T07:40:23Z"
},
{
"id": 33554749,
"type": "email",
"value": "someone#example.com",
"editedBy": "OWNER",
"flags": [],
"categories": [],
"updated": "2012-12-23T07:40:23Z",
"created": "2012-12-23T07:40:23Z"
}
]
}
]
}
}
You need to go with the following structure:
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
}
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public string[] flags { get; set; }
public string[] categories { get; set; }
public DateTime updated { get; set; }
public DateTime created { get; set; }
}
public class Name
{
public string givenName { get; set; }
public string middleName { get; set; }
public string familyName { get; set; }
public string prefix { get; set; }
public string suffix { get; set; }
public string givenNameSound { get; set; }
public string familyNameSound { get; set; }
}
And then deserialize it and use LINQ to manipulate fields.
If you want to stick to JObject and not create classes, look at the example provided at http://weblog.west-wind.com/posts/2012/Aug/30/Using-JSONNET-for-dynamic-JSON-parsing
You'll have to enumerate over this
dynamic contacts = (JArray)json["contacts"]
foreach(dynamic contact in contacts.contact) {
// look at the fields...
}
PS. Give it a go, don't have VS on me so cant quite verify the exact syntax
Firstly, I think you'll find that your JSON is not well-formed. You don't need the extra commas after the two "created" dates and there is a right-square bracket missing before the second last curly brace. I recommend you always validate your JSON using this awesome site: http://jsonformatter.curiousconcept.com
Secondly, you are not referencing the array elements correctly. Although I agree with #grundy that you should be creating class definitions for managing JSON and using LINQ, there is absolutely nothing wrong with the Newtonsoft library. You can still persist with your method.
Try this:-
var json = JObject.Parse(returnStr);
var fields = (JArray)json["contacts"]["contact"][0]["fields"];
var givenName = fields[0]["value"]["givenName"];
var familyName = fields[0]["value"]["familyName"];
var email = fields[1]["value"];

Categories

Resources