I wrote an application which is used to import new data from people into a database. The data I get is located on the web, that's working fine.
I used to work with the following structure:
{
"users": [
{
"firstname": "John",
"lastname": "Doe",
"id": "1",
"rfid": "BCDA412EA"
},
{
"firstname": "Jane",
"lastname": "Doe",
"id": "2",
"rfid": "DA412EBCA"
}
]
}
However, I got a new "structure" that I can not handle. The new nodes are random generated values? How can I access those?
New json looks like this:
{
"page": 0,
"page_size": 200,
"total_count": 5,
"count": 5,
"data": {
"ab90708-ded183ab37b55-623f-42ae-ae51": {
"firstname": "John",
"lastname": "Doe",
"created_at": "2015-09-16T15:51:39Z",
"tags": [
"803504",
"80363004",
"8436E64",
"test123"
]
},
"34ba-0619-4ed8-bf168d2a-ce3af684a2b0": {
"firstname": "Stefan",
"lastname": "Baloh",
"created_at": "2015-09-16T15:51:40Z",
"tags": [
"8034E26A4B0034004",
"F3626A4B0034035"
]
}
}
}
Is it even possible to work with such a structure?
You can declare your classes as
public class User
{
public string firstname { get; set; }
public string lastname { get; set; }
public string created_at { get; set; }
public List<string> tags { get; set; }
}
public class RootObject
{
public int page { get; set; }
public int page_size { get; set; }
public int total_count { get; set; }
public int count { get; set; }
public Dictionary<string, User> data { get; set; }
}
And deserialize as (using Json.Net)
var obj = JsonConvert.DeserializeObject<RootObject>(json);
foreach(var user in obj.data.Values)
{
Console.WriteLine(user.lastname);
}
The keyword here is the use of Dictionary<string,...> for these random names..
Related
I have the following JSON
[
{
"id": 1,
"firstName": "Smith",
"lastName": "Bill",
"emails": [
{
"id": 1,
"email": "Bill#Smith.Com",
"dateCreated": "2017-05-11T10:18:52.3224545-07:00"
},
{
"id": 2,
"email": "Bill#gmail.com",
"dateCreated": "2017-05-11T10:20:05.9283127-07:00"
}
]
},
{
"id": 2,
"firstName": "Bill",
"lastName": "Smith",
"emails": []
}
]
The email model object is inside the person.
I want to know how to use an LINQ statement to return me all the people that have emails that match some input. Such as if I search for "Bill#gmail.com", it would only return
[
{
"id": 1,
"firstName": "Smith",
"lastName": "Bill",
"emails": [
{
"id": 1,
"email": "Bill#Smith.Com",
"dateCreated": "2017-05-11T10:18:52.3224545-07:00"
},
{
"id": 2,
"email": "Bill#gmail.com",
"dateCreated": "2017-05-11T10:20:05.9283127-07:00"
}
]
}
]
It should look something like the follow?
var personWithEmail = People.FirstOrDefault(e => e.Id == i);
except this is only finding the People with some ID while I want to drill down to their children's email and search if the emails match.
Assuming People is a collection of Person
where
public class People : Collection<Person> { }
public class Person {
public int id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public IList<Email> emails { get; set; }
}
public class Email {
public int id { get; set; }
public string email { get; set; }
public DateTime dateCreated { get; set; }
}
Drill into the child properties.
var email = "Bill#gmail.com";
var people = JsonConvert.DeserializeObjecct<People>(json);
var peopleWithEmail = people.Where(p => p.emails.Any(e => e.email == email));
Adding another example to the list:
string input = "Bill#gmail.com";
List<Peeps> tmp = JsonConvert.DeserializeObject<List<Peeps>>(json);
//returns the base object
var test = tmp.Where(a => a.emails.Any(b => b.email == input));
//returns only the email object
var testDuece = tmp.Where(a => a.emails.Any(b => b.email == input)).Select(c => c.emails.Where(a => a.email == input));
public class Peeps
{
public int id { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public List<Emails> emails { get; set; }
}
public class Emails
{
public int id { get; set; }
public string email { get; set; }
public string dateCreated { get; set; }
}
I have a noSQL database. When I'm trying to map the JSON data with C# class models, some of my data get mapped, but some don't.
Below is my Sample JSON format.
{
"J1D0GhKmzAT4gRn5VkfPKKVCfku2": {
"reports": {
"-KYbi7tbJoZJmCs8hcHy": {
"age": "0",
"description": "Test",
"incident": "Test",
"location": "Test"
},
"-KYbmoWJwzSSS0llsSZN": {
"age": "0",
"description": "Test",
"incident": "Test",
"location": "Test"
},
"-KYbszjzkYnH2N9xbFMJ": {
"age": "0",
"description": "Test",
"incident": "Test",
"location": "Test"
}
},
"user_info": {
"dob": "Feb 11, 2016",
"name": "Test",
"phone": "44444",
"sex": "Male",
"work": "llllll"
}
},
"JxmpIWWioFbg1Po4gXtV07pwDvX2": {
"reports": {
"-KYiiDRl7fYAPdav13h3": {
"age": "0",
"description": "Test",
"incident": "Test",
"location": "Test"
},
"-KYinWZeP7N24x8QUC6O": {
"age": "0",
"description": "Test",
"incident": "Test",
"location": "Test"
}
},
"user_info": {
"dob": "Feb 11, 2016",
"name": "Test",
"phone": "44444",
"sex": "Male",
"work": "llllll"
}
}
}
and My C# Class Models are as below
public class User
{
public user_info user_info { get; set; }
public reports reports { get; set; }
}
public class user_info
{
public string dob { get; set; }
public string name { get; set; }
public string phone { get; set; }
public string sex { get; set; }
public string work { get; set; }
}
public class reports
{
public List<reportInfo> reportInfo { get; set; }
}
public class reportInfo
{
public string age { get; set; }
public string description { get; set; }
public string incident { get; set; }
public string location { get; set; }
}
Here, when I try to map the JSON with C# classes, only the user_info model gets populated for some reason. There is a matching property in JSON. But my reports model doesn't get populated, because it has some dynamic properties which is not getting mapped with model.
Please let me know where I am going wrong and the possible solution.
Thanks in advance.
Following dbc advice, you should modify your model.
Delete the reports class and modify User class like this:
public class User
{
public user_info user_info { get; set; }
public Dictionary<string, reportInfo> reports { get; set; }
}
I have to:
DeserializeObject - do some changes - SerializeObject
When my Json have miltiple types e.g.
{
"type": "test",
"currentStatus": "Active",
"id": "987",
"items": [
{
"type": "test1",
"id": "123",
"name": "Segment Members",
"memberCount": "0",
"outputTerminals": [
{
"type": "test2",
"id": "123",
"connectedId": "123",
"terminalType": "out"
}
],
"position": {
"type": "Position",
"x": "46",
"y": "14"
},
"isFinished": "true",
"isRecurring": "false",
"segmentId": "123"
},
{
"type": "test5",
"id": "1390",
"name": "Yay! Clickers",
"memberCount": "2",
"position": {
"type": "Position",
"x": "330",
"y": "375"
},
"waitFor": "2592000"
},
{
"type": "test3",
"id": "1391",
"name": "test",
"memberCount": "73",
"outputTerminals": [
{
"type": "test4",
"id": "123",
"connectedId": "123",
"connectedType": "CampaignWaitAction",
"terminalType": "yes"
},
{
"type": "test4",
"id": "123",
"connectedId": "123",
"connectedType": "CampaignWaitAction",
"terminalType": "no"
}
],
"position": {
"type": "Position",
"x": "123",
"y": "123"
},
"testId": "123"
}
]
}
What data type i should use for this operation? dynamic, object, Jobject...? or maybe something else?
I would just create an object and deseriablize it to that type. A lot easier than doing it dynamically. (assuming it will stay in that structure always)
WHAT TO DO
Copy your Json:
`Edit` -> `Paste Special` -> `Paste JSON As CLASSES`
And there you go! You have the Type you want to deserialize to.
var deserializedJson = JsonConvert.DeserializeObject<YourNewObject>(jsonString);
Note: if the pasting of the json class doesn't work, make sure your json is valid: ClickHereToValidateJson
using Newtonsoft.Json;
dynamic collection = new
{
MultipleType = //call function which returns json here
};
//serialize
var jsonSerializedFeed = JsonConvert.SerializeObject(MultipleType);
//deserialize
var jsonSerializedFeed = JsonConvert.DeserializeObject(MultipleType);
Hope it helps
You can create classes and serialize/deserialize json:
public class OutputTerminal
{
public string type { get; set; }
public string id { get; set; }
public string connectedId { get; set; }
public string terminalType { get; set; }
public string connectedType { get; set; }
}
public class Position
{
public string type { get; set; }
public string x { get; set; }
public string y { get; set; }
}
public class Item
{
public string type { get; set; }
public string id { get; set; }
public string name { get; set; }
public string memberCount { get; set; }
public IList<OutputTerminal> outputTerminals { get; set; }
public Position position { get; set; }
public string isFinished { get; set; }
public string isRecurring { get; set; }
public string segmentId { get; set; }
public string waitFor { get; set; }
public string testId { get; set; }
}
public class Root
{
public string type { get; set; }
public string currentStatus { get; set; }
public string id { get; set; }
public IList<Item> items { get; set; }
}
And then:
string json = JsonConvert.SerializeObject(rootObject);
Root root = JsonConvert.DeserializeObject<Root>(json);
Also, you can use dynamic type without classes:
string json = JsonConvert.SerializeObject(dynamicObject);
dynamic obj = JsonConvert.DeserializeObject(json);
I cannot deserialized the following data which I'm using for testing and got it from the World Bank using the following query:
http://api.worldbank.org/countries/IRL/indicators/SP.DYN.CBRT.IN?
per_page=10&date=1960:2016&format=json
[
{
"page": 1,
"pages": 28,
"per_page": "2",
"total": 56
},
[
{
"indicator": {
"id": "SP.DYN.CBRT.IN",
"value": "Birth rate, crude (per 1,000 people)"
},
"country": {
"id": "IE",
"value": "Ireland"
},
"value": "21.2",
"decimal": "0",
"date": "1961"
},
{
"indicator": {
"id": "SP.DYN.CBRT.IN",
"value": "Birth rate, crude (per 1,000 people)"
},
"country": {
"id": "IE",
"value": "Ireland"
},
"value": "21.5",
"decimal": "0",
"date": "1960"
}
]
]
My main class is called PageModel is defined as such:
public class PageModel
{
public PageModel()
{
this.List = new List<Data>();
}
[JsonProperty("page")]
public int Page { get; set; }
[JsonProperty("pages")]
public int Pages { get; set; }
[JsonProperty("per_page")]
public string PerPage { get; set; }
[JsonProperty("total")]
public int Total { get; set; }
public List<Data> List { get; set; }
}
The class used in the array is called Data and is defined as follows:
public class Data
{
public Data()
{
this.Indicator = new Indicator();
this.Country = new Country();
}
[JsonProperty("indicator")]
public Indicator Indicator { get; set; }
[JsonProperty("country")]
public Country Country { get; set; }
[JsonProperty("date")]
public int Date { get; set; }
[JsonProperty("value")]
public float Value { get; set; }
[JsonProperty("decimal")]
public decimal Decimal { get; set; }
}
Both the Country and Indicator classes are defined as follows:
public class Country
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
public class Indicator
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
My HttpClient call returns the data correctly but whenever I try to deserialize the data using the NewtonSoft JsonConvert.DeserializeObject function:
PageModel pageModel = JsonConvert.DeserializeObject<PageModel>(data);
It returns null.
Any ideas why?
Thanks.
Your JSON data is in wrong format:
Change your json to this and it will work:
{
"page": 1,
"pages": 28,
"per_page": "2",
"total": 56,
"List":[
{
"indicator": {
"id": "SP.DYN.CBRT.IN",
"value": "Birth rate, crude (per 1,000 people)"
},
"country": {
"id": "IE",
"value": "Ireland"
},
"value": "21.2",
"decimal": "0",
"date": "1961"
},
{
"indicator": {
"id": "SP.DYN.CBRT.IN",
"value": "Birth rate, crude (per 1,000 people)"
},
"country": {
"id": "IE",
"value": "Ireland"
},
"value": "21.5",
"decimal": "0",
"date": "1960"
}
]
}
here is my json response that I am trying to deserialize
[{
"Musician": {
"id": "554343",
"Name": "16408",
"Age": "22"
},
"Albums": [{
"id": "34343",
"AlbumName": "Super charge",
"ReleaseDate": "",
"Hits": ""
}, {
"id": "34222",
"AlbumName": "Super 2",
"ReleaseDate": "",
"Hits": ""
}]
},
{
"Musician": {
"id": "554344",
"Name": "16468",
"Age": "32"
},
"Albums": [{
"id": "34323",
"AlbumName": "Awesome one",
"ReleaseDate": "",
"Hits": ""
}, {
"id": "34222",
"AlbumName": "Awesome two",
"ReleaseDate": "",
"Hits": ""
}]
}]
here are my class
public class Musician
{
public string id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
}
public class Album
{
public string id { get; set; }
public string AlbumName { get; set; }
public string ReleaseDate { get; set; }
public string Hits { get; set; }
}
public class RootObject
{
public Musician Musician { get; set; }
public List<Album> Albums { get; set; }
}
this is the code i am using to deserialize objects
var musicians = JsonConvert.DeserializeObject<List<Musician>>(data);
var album = JsonConvert.DeserializeObject<List<Album>>(data);
musicians variable shows 2 counts of record while debugging but value of elements id,Name,Age always shows null. Not able to recognize what exactly causing it.
You should be deserializing as collection of RootObjects.
var musicians = JsonConvert.DeserializeObject<IEnumerable<RootObject>>(data);
Output