Can't deserialize JSON into C# POCO - c#

I can't convert JSON Object into C# class object I've tried many things but the same error pops up:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[CoderwallDotNet.Api.Models.Account]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
I am using this JSON and tring to get the response in windows 8.1 application.
[
{
"id": 1,
"time": 40,
"srcLong": 35.909124,
"srcLat": 31.973628,
"destLong": 35.898258,
"destLat": 31.985622,
"subSites": [
{
"id": 1,
"name": "location1"
},
{
"id": 2,
"name": "location2"
},
{
"id": 3,
"name": "locaion3"
}
]
}]
and the I tried to read from the JSON using webclient but its not working it can't recognize it so I am using Newtonsoft.Json and I creted these class to get the response.
public class SubSite
{
public int id { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public int time { get; set; }
public double srcLong { get; set; }
public double srcLat { get; set; }
public double destLong { get; set; }
public double destLat { get; set; }
public List<SubSite> subSites { get; set; }
}
var serviceUri = "http://localhost:24728/api/sites";
var client = new HttpClient();
var response = await client.GetAsync(serviceUri);
var datafile = await response.Content.ReadAsStringAsyn();
List<RootObject> data = JsonConvert.DeserializeObject<List<RootObject>>(datafile);
test1234.Text = data.ToString();//i am trying to for eample destlat
but I can't get the value I am getting the response and everything is fine but idk how to put it into object and use it where ever I want. For example, I want to get the value of time and the other but I have problem with List of subsites or get the location inside the subsites or srclong or srclat and here is the project how to get the Json to c# object:
https://onedrive.live.com/?cid=e648f5a0f179f346&id=E648F5A0F179F346%218429&ithint=folder,rar&authkey=!ALKlJdwsb8ER2FA

This works fine:
var data = JsonConvert.DeserializeObject<RootObject>(datafile)

You can deserialize into a dynamic object if you are not too particular about losing intellisense. One advantage to using a dynamic is that you don't have to create classes just to be able to deserialize and also that you don't need to update your class structures if the returned data has changed. As an example you can do this:
dynamic jsonValue = JsonConvert.DeserializeObject(jsonData);
foreach (dynamic rootObject in jsonValue)
{
theData.destLong.Value <-- use it anyway you want, store in a variable, etc.
// to get to each of the subSite in the rootObject
foreach (dynamic subSite in rootObject.subSites)
{
subSite.id.Value <-- returns an int based on your data
subSite.name.Value <-- returns a string based on your data
}
}
// where jsonData constains the json string you posted
The foreaeach is important because the data you posted will result into an array. You can also just do a jsonValue[0] but watch out for errors for null values, which you should be checking anyway starting with the returned json string.

Related

Extract specific data from JSON

I have the following code in my app (using Newton.Json):
var data = JsonConvert.DeserializeObject(responseValue).ToString();
Using the following code:
Console.WriteLine(data);
I get:
{
"result": "some random string goes here",
"error": null,
"id": "1"
}
How do I get the string from the result part of the JSON in the data variable, and put it into its own variable for later use?
If you have a C# class that corresponds to the "shape" of the JSON (same properties with the same data type):
public class ResponseType
{
public string Result { get; set; }
public string Error { get; set; }
public int Id { get; set; }
}
you can do:
ResponseType data = JsonConvert.DeserializeObject<ResponseType>(responseValue);
and then access each property of that class:
string result = data.Result;
This can be done without deserialization.
var json = JObject.Parse(responseValue);
var result = json["result"];
Open namespace.
using Newtonsoft.Json.Linq;

Json formatting error message when making GET HTTP Call

i'm trying to return a list of users from our software and format the names and email addresses of these users into a list so can compare this to other lists and determine what is more accurate. i'm making the request using the code below.
Question: How do I format my code to accept a json array as the error message states?
public void MakeCall()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Url);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(_urlParameters).Result;
if (response.IsSuccessStatusCode)
{
var dataObjects = response.Content.ReadAsAsync<IEnumerable<WorkfrontDataObjects>>().Result;
foreach (var workfrontData in dataObjects)
{
Console.WriteLine("{0}", workfrontData.Email);
}
}
Console.ReadLine();
}
public class WorkfrontDataObjects
{
public string[] Email { get; set; }
public string[] Name { get; set; }
public WorkfrontDataObjects()
{
}
}
Error Message:
JsonSerializationException: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
'System.Collections.Generic.IEnumerable`1[ManageWorkfrontADUserDistros.WorkfrontDataObjects]'
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 'data', line 1, position 8.
UPDATE, adding json:
{
"data": [
{
"ID": "000000000000000000000000000000",
"name": "name",
"objCode": "USER",
"emailAddr": "email"
},
{
"ID": "000000000000000000000000000000",
"name": "name",
"objCode": "USER",
"emailAddr": "email"
},
2500 of whats above with obviously real data
Given your JSON, your model needs to look like this:
public class RootObject
{
[JsonProperty("data")]
public List<Item> Data { get; set; }
}
public class Item
{
[JsonProperty("ID")]
public string ID { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("objCode")]
public string ObjCode { get; set; }
[JsonProperty("emailAddr")]
public string Email { get; set; }
}
You can rename the classes and properties to suit your needs without affecting the deserialization, as long as the names in the [JsonProperty] attributes match the JSON.
Then you should be able to receive the data like this:
if (response.IsSuccessStatusCode)
{
var rootObject = response.Content.ReadAsAsync<RootObject>().Result;
foreach (var item in rootObject.Data)
{
Console.WriteLine(item.Email);
}
}
Your string[] should be string in WorkfrontDataObjects and email should be emailAddr

Deserializing an array of objects with Json.Net

The received data is like this:
Inside each item, there is an object, customer, I have an identical class for that. How can I convert them using Json.net?
I have tried the followings:
var data = JsonConvert.DeserializeObject<List<customer>>(val);
and adding another class:
public class customerJson
{
public Customer customer{ get; set; }
}
And trying to deserialize it:
var data = JsonConvert.DeserializeObject<List<customerJson>>(val);
With both of them I get an exception:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[customer]' 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 'rows', line 1, position 8.
Data:
{"rows":[{"id":"232333","name":"nam"},{"id":"3434444","name":"2ndName"}]}
If I read your json data structure correctly you would want this:
public class Root
{
public List<Customer> rows { get; set; }
}
and
var data = JsonConvert.DeserializeObject<Root>(val);
Tested code:
void Main()
{
var test = JsonConvert.DeserializeObject<Root>("{\"rows\":[{\"id\":\"232333\",\"name\":\"nam\"},{\"id\":\"3434444\",\"name\":\"2ndName\"}]}");
Console.WriteLine(test.rows[0].id); // prints 232333
}
public class Customer
{
public int id { get; set; }
}
public class Root
{
public List<Customer> rows { get; set; }
}
Just in case anyone is still having issues. This worked out for me:
If the Json looks something like this:
"result": [
{
"firstname": "John",
"lastname": "Doe",
},
{
"firstname": "Max",
"lastname": "Mustermann",
}
]
ResultList.cs
public class ResultList {
[JsonProperty("result")]
public List<ResultObj> ResultObj { get; set }
}
ResultObj.cs
public class ResultObj {
[JsonProperty("firstname")]
public string FirstName { get; set; }
[JsonProperty("lastname")]
public string LastName{ get; set; }
}
And finally:
using Newtonsoft.Json;
var resultList = JsonConvert.DeserializeObject<ResultList>(jsonString);

Deserializing nested JSON arrays using RestSharp

I'm trying to deserialize the following JSON response using RestSharp. I have tried various model structures to extract the data to no avail. I keep getting tripped up on the nested arrays.
I do not have control over the service, so I can't change the format.
JSON Format:
[
{
"results": 19,
"statuscode": 200,
},
[
{
"id": 24,
"name": "bob"
},
{
"id": 82,
"name": "alice"
}
]
]
Using this model, I've been able to pull the data from the first object, but that's all. I'm not sure how exactly to read through the array that comes after the object.
public class Info
{
public int results { get; set; }
public int statuscode { get; set; }
}
Example deseralization:
var deserializer = new JsonDeserializer();
var wat = deserializer.Deserialize<List<List<Info>>>(response);
Am I just completely missing something here or are my only options to write a custom deserializer and/or use something like JSON.NET?
The problem is that your JSON array is exceptionally polymorphic: its first element is an object, and its second element is an array of objects. A more natural way to represent this would have been as a JSON object with two named properties -- but that's not what you have been given. Deserializing this directly to a c# POCO with two named properties in a single step with any serializer is going to be tricky since the JSON data model is quite different than your desired data model. Instead, it may be easiest to deserialize to an intermediate representation and convert. Luckily RestSharp has appropriate intermediate classes JsonObject and JsonArray.
Thus, if you want to deserialize to the following classes:
public class Info
{
public int results { get; set; }
public int statuscode { get; set; }
}
public class IdAndName
{
public int id { get; set; }
public string name { get; set; }
}
public class ResponseContent
{
public Info Info { get; set; }
public List<IdAndName> Data { get; set; }
}
You can do:
var array = (JsonArray)SimpleJson.DeserializeObject(response.Content);
var responseContent = (array == null ? (ResponseContent)null : new ResponseContent()
{
Info = array.OfType<JsonObject>().Select(o => SimpleJson.DeserializeObject<Info>(o.ToString())).FirstOrDefault(),
Data = array.OfType<JsonArray>().SelectMany(a => SimpleJson.DeserializeObject<List<IdAndName>>(a.ToString())).ToList()
});

Deserializing JSON data to C# using JSON.NET

I'm relatively new to working with C# and JSON data and am seeking guidance. I'm using C# 3.0, with .NET3.5SP1, and JSON.NET 3.5r6.
I have a defined C# class that I need to populate from a JSON structure. However, not every JSON structure for an entry that is retrieved from the web service contains all possible attributes that are defined within the C# class.
I've been being doing what seems to be the wrong, hard way and just picking out each value one by one from the JObject and transforming the string into the desired class property.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
What is the best way to deserialize a JSON structure into the C# class and handling possible missing data from the JSON source?
My class is defined as:
public class MyAccount
{
[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }
[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }
[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }
[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }
[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }
[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }
[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }
[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }
[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }
[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }
[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }
[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }
[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }
[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }
[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }
}
And a sample of the JSON to parse is:
{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
Use
var rootObject = JsonConvert.DeserializeObject<RootObject>(string json);
Create your classes on JSON 2 C#
Json.NET documentation: Serializing and Deserializing JSON with Json.NET
Have you tried using the generic DeserializeObject method?
JsonConvert.DeserializeObject<MyAccount>(myjsondata);
Any missing fields in the JSON data should simply be left NULL.
UPDATE:
If the JSON string is an array, try this:
var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);
jarray should then be a List<MyAccount>.
ANOTHER UPDATE:
The exception you're getting isn't consistent with an array of objects- I think the serializer is having problems with your Dictionary-typed accountstatusmodifiedby property.
Try excluding the accountstatusmodifiedby property from the serialization and see if that helps. If it does, you may need to represent that property differently.
Documentation: Serializing and Deserializing JSON with Json.NET
You can use:
JsonConvert.PopulateObject(json, obj);
here: json is the json string,obj is the target object. See: example
Note: PopulateObject() will not erase obj's list data, after Populate(), obj's list member will contains its original data and data from json string
Building off of bbant's answer, this is my complete solution for deserializing JSON from a remote URL.
using Newtonsoft.Json;
using System.Net.Http;
namespace Base
{
public class ApiConsumer<T>
{
public T data;
private string url;
public CalendarApiConsumer(string url)
{
this.url = url;
this.data = getItems();
}
private T getItems()
{
T result = default(T);
HttpClient client = new HttpClient();
// This allows for debugging possible JSON issues
var settings = new JsonSerializerSettings
{
Error = (sender, args) =>
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
}
};
using (HttpResponseMessage response = client.GetAsync(this.url).Result)
{
if (response.IsSuccessStatusCode)
{
result = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result, settings);
}
}
return result;
}
}
}
Usage would be like:
ApiConsumer<FeedResult> feed = new ApiConsumer<FeedResult>("http://example.info/feeds/feeds.aspx?alt=json-in-script");
Where FeedResult is the class generated using the Xamasoft JSON Class Generator
Here is a screenshot of the settings I used, allowing for weird property names which the web version could not account for.
I found my I had built my object incorrectly. I used http://json2csharp.com/ to generate me my object class from the JSON. Once I had the correct Oject I was able to cast without issue. Norbit, Noob mistake. Thought I'd add it in case you have the same issue.
You can try checking some of the class generators online for further information. However, I believe some of the answers have been useful. Here's my approach that may be useful.
The following code was made with a dynamic method in mind.
dynObj = (JArray) JsonConvert.DeserializeObject(nvm);
foreach(JObject item in dynObj) {
foreach(JObject trend in item["trends"]) {
Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]);
}
}
This code basically allows you to access members contained in the Json string. Just a different way without the need of the classes. query, trend and url are the objects contained in the Json string.
You can also use this website. Don't trust the classes a 100% but you get the idea.
Assuming your sample data is correct, your givenname, and other entries wrapped in brackets are arrays in JS... you'll want to use List for those data types. and List for say accountstatusexpmaxdate... I think you example has the dates incorrectly formatted though, so uncertain as to what else is incorrect in your example.
This is an old post, but wanted to make note of the issues.

Categories