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; }
}
Related
I get the data from the web server as json, but I can't deserialize them and access the keys (eg first_name)
The information is received in the client, but Unfortunately, this code does not print anything in the Unity console
my code :
socket.On("UserList", response =>
{
var result = JsonConvert.DeserializeObject<List<UserClass>>(response.ToString());
var first_name = result[0].first_name;
print(first_name);
});
UserClass :
public class UserClass
{
public string _id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string mobile { get; set; }
public string email { get; set; }
public DateTime createdAt { get; set; }
public DateTime updateAt { get; set; }
public int __v { get; set; }
}
Json that is received in the client :
[
{
"_id": "83ca7d56cbc2b281wd4ee658",
"first_name": "sara",
"last_name": "Paulson",
"mobile": "09323456789",
"email": "sara#gmail.com",
"createdAt": "2023-01-20T12:46:38.384Z",
"updateAt": "2023-01-20T12:46:38.384Z",
"__v": 0
},
{
"_id": "59e41dku510239e83ed7e10m",
"first_name": "Evan",
"last_name": "Peters",
"mobile": "09327931248",
"email": "Evan#gmail.com",
"createdAt": "2023-02-10T10:35:26.687Z",
"updateAt": "2023-02-10T10:35:26.687Z",
"__v": 0
},
{
"_id": "64lm96c57a8a4f289fw0gg66",
"first_name": "Emma",
"last_name": "Roberts",
"mobile": "09325354769",
"email": "Emma#gmail.com",
"createdAt": "2023-01-20T13:11:46.402Z",
"updateAt": "2023-01-20T13:11:46.402Z",
"__v": 0
}
]
How can I access keys of this Json in Unity?
I checked and found that even specifying arrays in JSON works somehow:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
class UserClass
{
public string _id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string mobile { get; set; }
public string email { get; set; }
public DateTime createdAt { get; set; }
public DateTime updateAt { get; set; }
public int __v { get; set; }
}
class UserList
{
public List<UserClass> objs;
}
public class Program
{
public static void Main(string[] args)
{
string response = "{'objs': [{'_id': 1, 'first_name': 'abc'}, {'_id': 2, 'first_name': 'def'}]}";
var result = JsonConvert.DeserializeObject<UserList>(response);
if (result != null)
{
foreach (UserClass u in result.objs)
{
Console.Write(u._id + ',');
Console.WriteLine(u.first_name);
}
}
string response2 = "[{'_id': 1, 'first_name': 'abc'}, {'_id': 2, 'first_name': 'def'}]";
var result2 = JsonConvert.DeserializeObject<List<UserClass>>(response2);
if (result2 != null)
{
for (var i = 0; i < result2.Count; i++)
{
Console.Write(result2[i]._id + ',');
Console.WriteLine(result2[i].first_name);
}
}
}
}
Both ways give same output. https://dotnetfiddle.net/g2Dn1n
The only additional thing I did was to check for returned value. You should use Debug.Log() in Unity to print actual values obtained after deserialization.
This is my first question, I hope to do it correctly.
I am starting to use an ASP.NET Core Web API and I have a question.
I have the following models:
public class Pokemon
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public ICollection<Review> Reviews { get; set; }
public ICollection<PokemonOwner> PokemonOwners { get; set; }
public ICollection<PokemonCategory> PokemonCategories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<PokemonCategory> PokemonCategories { get; set; }
}
public class PokemonCategory
{
public int PokemonId { get; set; }
public int CategoryId { get; set; }
public Pokemon Pokemon { get; set; }
public Category Category { get; set; }
}
I'm trying to display in an endpoint of my controller where it shows me together the pokemons and their corresponding category.
I have tried to make a join between the two tables but it is impossible to get the expected result (return the pokemons and its category).
public List<Category> GetPokemonAndCategory(int pokemonid, int categoryid)
{
return _context.Categories
.Include(a => a.PokemonCategories)
.Where(c => c.Id == categoryid).ToList();
}
With this code, I get this data returned:
[
{
"id": 2,
"name": "Water",
"pokemonCategories": [
{
"pokemonId": 2,
"categoryId": 2,
"pokemon": null,
"category": null
}
]
}
]
Can you help me? Thanks!
Return pokemons and categories in the same query
EDIT
This works with cemahseri answer, if i change the DTO for something like this;
public class PokemonCategoryDto
{
public Pokemon Pokemon { get; set; }
// public Category Category { get; set; }
}
but i get this result;
{
"pokemon": {
"id": 2,
"name": "Squirtle",
"birthDate": "1903-01-01T00:00:00",
"reviews": null,
"pokemonOwners": null,
"pokemonCategories": [
{
"pokemonId": 2,
"categoryId": 2,
"pokemon": null,
"category": {
"id": 2,
"name": "Water",
"pokemonCategories": [
null
]
}
}
]
}
}
i think is because mi pokemon class have the other classes, how i can not show it like this?
{
"pokemon": {
"id": 2,
"name": "Squirtle",
"birthDate": "1903-01-01T00:00:00",
"pokemonCategories": [
{
"pokemonId": 2,
"categoryId": 2,
"category": {
"id": 2,
"name": "Water",
}
}
]
}
}
You can create DTO and return any data you want from that action. It's also recommended to use DTOs. Because sometimes you might not want to expose all properties in those classes. For example, let's say you have a DTO like this;
public class PokemonDto
{
public Pokemon Pokemon { get; set; }
public Category Category { get; set; }
}
Then you can get Pokémon and its category then return it from the action like this;
public async Task<IActionResult> GetPokemons(int pokemonId, int categoryId)
{
var pokemon = await _databaseContext.Pokemons.FirstOrDefaultAsync(p => p.Id == pokemonId);
var category = await _databaseContext.Categories.FirstOrDefaultAsync(c => c.Id == categoryId);
return Ok(new PokemonDto
{
Pokemon = pokemon,
Category = category
});
}
I have a json string.
There are multiple subcategories within the json string depending on the category.
I want to combine them all.
It should always give the Id of the last child level of a higher level.
Sample :
Id - Name
-- ----------
1239 - Accessory> Jewelery > wristband> Silver wristband
Can anyone help me . Thanks
{
"categories": [
{
"id": 368,
**"name": "Accessory ",**
"parentId": null,
"subCategories": [
{
"id": 396,
**"name": "Jewelery ",**
"parentId": 368,
"subCategories": [
{
"id": 397,
**"name": "wristband",**
"parentId": 396,
"subCategories": [
{
"id": 1238,
"name": "Gold wristband",
"parentId": 397,
"subCategories": []
},
{
**"id": 1239,**
"name": "Silver wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 2845,
"name": "Steel wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 3171,
"name": "Pearl wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 3883,
"name": "diamond wristband",
"parentId": 397,
"subCategories": []
}
]
}
]
}
]
}
]
}
Here my class
public class SubCategory
{
public int id { get; set; }
public string name { get; set; }
public int parentId { get; set; }
public List<object> subCategories { get; set; }
}
public class Category
{
public int id { get; set; }
public string name { get; set; }
public object parentId { get; set; }
public List<SubCategory> subCategories { get; set; }
}
public class Root
{
public List<Category> categories { get; set; }
}
I think you can drop SubCategory, what is that List<object> doing there anyway?
Assuming you can deserialize
public class Category
{
public int id { get; set; }
public string name { get; set; }
public int? parentId { get; set; } // int?
public List<Category> subCategories { get; set; } // <Category>
}
public class Root
{
public List<Category> categories { get; set; }
}
then you can use a simple depth-first recursive visitor:
string FindCategoryTrail(List<Category> categories, int id)
{
foreach(var category in categories)
{
if (category.id == id) return category.name;
var trail = FindCategoryTrail(category.subCategories , id);
if (trail != null)
{
return category.name + " > " + trail;
}
}
return null;
}
and call it like
string trail = FindCategoryTrail(myRoot.categories, 1239);
using Linq, you could flatten the nested lists:
public class Category
{
public int id { get; set; }
public string name { get; set; }
public object parentId { get; set; }
public List<Category> subCategories { get; set; }
}
public class Root
{
public List<Category> categories { get; set; }
}
IEnumerable<Category> Flatten(IEnumerable<Category> e) => e.SelectMany(c => Flatten(c.subCategories)).Concat(e);
Root root = JsonConvert.DeserializeObject<Root>(File.ReadAllText(#"U:\test1.json"));
var search = Flatten(root.categories).Where(c => c.id == 1239);
foreach(var s in search)
{
System.Diagnostics.Debug.WriteLine($"id: {s.id}");
System.Diagnostics.Debug.WriteLine($"name: {s.name}");
System.Diagnostics.Debug.WriteLine($"parentid: {s.parentId}");
}
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..
I'm using a Web-API GET to return JSON for a Report.
The GET method returns a simple db.Reports.ToList();
This is the dump of the data I retrieve
{
"Project": {
"Location": {
"LocationId": 7,
"Description": "New York"
},
"Department": {
"DepartmentId": 7,
"Description": "Engineering"
},
"ProjectId": 7,
"Description": "Project_3",
"LocationId": 7,
"DepartmentId": 7
},
"Person": {
"Email": "email#gmail.com",
"FirstName": "John",
"LastName": "Doe",
"IsActive": true
},
"StatusCode": {
"StatusId": 8,
"Description": "Accepted"
},
"ReportId": "d4cddb3f-ea6a-4b0a-9820-19bd8ee43b3a",
"Description": "Report 3",
"RoundTrip": 45.88,
"IsBillable": true,
"StartDate": "2013-06-27T00:00:00",
"EndDate": "2013-06-27T14:36:32.467",
"TimeUpdated": "AAAAAAAAJxM="
}, ...
}
This is the related Report declaration:
public class Report
{
public Guid ReportId { get; set; }
public string Description { get; set; }
public double RoundTrip { get; set; }
public bool IsBillable { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public virtual Project Project { get; set; }
public byte[] TimeUpdated { get; set; }
public virtual Person Person { get; set; }
public virtual StatusCode StatusCode { get; set; }
}
In this situation, I'd really like to just have the Ids of the various objects contained in the Report class. For example, I'd really just like to see:
"Project": 7,
"Location": 7,
"Department": 7,
"Person": "email#gmail.com",
"StatusCode": 8,
"ReportId": "d4cddb3f-ea6a-4b0a-9820-19bd8ee43b3a",
"Description": "Report 3",
"RoundTrip": 45.88,
"IsBillable": true,
"StartDate": "2013-06-27T00:00:00",
"EndDate": "2013-06-27T14:36:32.467",
"TimeUpdated": "AAAAAAAAJxM="
Is there a relatively easy way to go about doing this, or would it be in my better interests to just further parse the result I'm seeing already?
Why does EF by default create these objects within the JSON rather than just the foreign keys?
You can do without specifically creating a new class. In your ApiController, if you are using the typed return type (in favor of an HttpResponseMessage), change the List type to IEnumerable<object> and return:
return db.Reports.Select(r => new {
Project = r.ProjectId;
Location = r.Location.LocationId;
Department = r.Department.DepartmentId;
Person = r.Person.Email;
StatusCode = r.StatusCode.StatusId;
Description: r.Description
RoundTrip: r.RoundTrip
IsBillable: r.IsBillable,
StartDate: r.StartDate,
EndDate: r.EndDate
TimeUpdated: r.TimeUpdated
});
// Or if you're using HttpResponseMessage
return Request.CreateResponse(HttpStatusCode.Ok,
db.Reports.Select(r => new {
Project = r.ProjectId;
Location = r.Location.LocationId;
Department = r.Department.DepartmentId;
Person = r.Person.Email;
StatusCode = r.StatusCode.StatusId;
Description: r.Description
RoundTrip: r.RoundTrip
IsBillable: r.IsBillable,
StartDate: r.StartDate,
EndDate: r.EndDate
TimeUpdated: r.TimeUpdated
}));
The default Json serializer (Newtonsoft's Json.Net) is smart enough to serialize anonymous object. The only unknown in the code above is the behaviour of the TimeUpdated member as it's a byte array. You may have to adjust the assignment.
I would recommend making a model for displaying the JSON as you want it to be displayed. This would be the easiest option.
Something like this should work:
public class ReportSimple
{
public Guid ReportId { get; set; }
public int Project { get; set; }
public int Location { get; set; }
public int Department { get; set; }
public string Person { get; set; }
public int StatusCode { get; set; }
public string Description { get; set; }
public double RoundTrip { get; set; }
public bool IsBillable { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public byte[] TimeUpdated { get; set; }
public ReportSimple(Project project, Person person, StatusCode statusCode)
{
Project = project.ProjectId;
Location = project.Location.LocationId;
Department = project.Department.DepartmentId;
Person = person.Email;
StatusCode = statusCode.StatusId;
}
}