I'm trying to display a paged table of "Albums" data in an MVC 5 application, with the data values coming from different records using the JSONPlaceholder REST API:
https://jsonplaceholder.typicode.com/
Users: (10 records)
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}
Albums: (100 records)
{
"userId": 1,
"id": 1,
"title": "quidem molestiae enim"
}
Photos: (5000 records)
{
"albumId": 1,
"id": 1,
"title": "accusamus beatae ad facilis cum similique qui sunt",
"url": "https://via.placeholder.com/600/92c952",
"thumbnailUrl": "https://via.placeholder.com/150/92c952"
}
The table will show fields from /users, /albums, and /photos. Some of the values are nested such as the address values for a user. I created the individual model classes using https://json2csharp.com/. Next I plan to create the AlbumsViewModel with the fields I need and IEnumerable properties for UserModel, AlbumModel and PhotoModel classes. I'm unsure of how to fetch the data from these different resources and how to represent the cardinality between these entities in the AlbumsViewModel to present a custom view which would display the following:
Thumbnail | Title | Name | Email | Phone | Address
View Model:
public class AlbumViewModel
{
public string ThumbnailUrl { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
}
UPDATE
I've got the records displaying but have two remaining issues:
1) Is there a more performant way of doing this than using three nested loops?
2) How to implement paging in MVC 5? I've seen the PagedList Nuget package (no longer maintained). Is this the best available option?
UPDATE 2
I have the paging implemented using the PagedList.MVC package. The only remaining problem is with the AlbumViewModel fields being populated from the three different resources. I originally thought it was just a performance issue but it looks like I'm doing it wrong. I'm getting 5000 records back; is this correct? Can anyone suggest a better, correct way of doing this? Maybe with LINQ?
public static class AlbumsModelBAL
{
private const string albumsAddress =
"http://jsonplaceholder.typicode.com/albums";
private const string usersAddress =
"http://jsonplaceholder.typicode.com/users"
private const string photosAddress =
"http://jsonplaceholder.typicode.com/photos";
public static List<AlbumViewModel> GetAlbums()
{
List<User> users = null;
List<AlbumModel> albums = null;
List<PhotoModel> photos = null;
AlbumViewModel albumVM = null;
List<AlbumViewModel> albumsList = new List<AlbumViewModel>();
string thumbnailURL, title, name, email, phone, address = string.Empty;
using (var client = new HttpClient())
{
var usersResponse = client.GetAsync(usersAddress).Result;
var albumsResponse = client.GetAsync(albumsAddress).Result;
var photosResponse = client.GetAsync(photosAddress).Result;
if (usersResponse.IsSuccessStatusCode && albumsResponse.IsSuccessStatusCode && photosResponse.IsSuccessStatusCode)
{
var usersResponseContent = usersResponse.Content;
string usersResponseString = usersResponseContent.ReadAsStringAsync().Result;
users = JsonConvert.DeserializeObject<List<User>>(usersResponseString);
var albumsResponseContent = albumsResponse.Content;
string albumsResponseString = albumsResponseContent.ReadAsStringAsync().Result;
albums = JsonConvert.DeserializeObject<List<AlbumModel>>(albumsResponseString);
var photosResponseContent = photosResponse.Content;
string photosResponseString = photosResponseContent.ReadAsStringAsync().Result;
photos = JsonConvert.DeserializeObject<List<PhotoModel>>(photosResponseString);
// This is the problem
for (int i = 0; i < users.Count; i++)
{
for (int j = 0; j < albums.Count; j++)
{
if (users[i].Id == albums[j].UserId)
for (int k = 0; k < photos.Count; k++)
{
if (albums[j].Id == photos[k].AlbumId)
{
thumbnailURL = photos[k].ThumbnailUrl;
title = albums[j].Title;
name = users[i].Name;
email = users[i].Email;
phone = users[i].Phone;
address = users[i].Address.Street + ", "
+ users[i].Address.Suite + ", "
+ users[i].Address.City + ", "
+ users[i].Address.Zipcode;
albumVM = new AlbumViewModel
{
ThumbnailUrl = thumbnailURL,
Title = title,
Name = name,
Email = email,
Phone = phone,
Address = address
};
albumsList.Add(albumVM);
}
}
}
}
}
}
return albumsList;
}