使用 JSONPlaceholder 和 MVC 5 处理相关记录
Handle Related Records with JSONPlaceholder and MVC 5
我正在尝试在 MVC 5 应用程序中显示分页 table 的“相册”数据,数据值来自使用 JSONPlaceholder REST 的不同记录 API:
https://jsonplaceholder.typicode.com/
用户:(10条记录)
{
"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"
}
}
相册:(100 条记录)
{
"userId": 1,
"id": 1,
"title": "quidem molestiae enim"
}
照片:(5000 条记录)
{
"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"
}
table 将显示来自 /users、/albums 和 /photos 的字段。一些值是嵌套的,例如用户的地址值。我使用 https://json2csharp.com/ 创建了个人模型 类。接下来,我计划使用我需要的字段和 UserModel、AlbumModel 和 PhotoModel 类 的 IEnumerable 属性创建 AlbumsViewModel。我不确定如何从这些不同的资源中获取数据以及如何在 AlbumsViewModel 中表示这些实体之间的基数以呈现将显示以下内容的自定义视图:
缩略图 |标题 |名称 |电邮 | Phone |地址
查看模型:
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; }
}
更新
我已经显示了记录,但还有两个问题:
1) 有没有比使用三个嵌套循环更高效的方法?
2)如何在MVC 5中实现分页?我看过 PagedList Nuget 包(不再维护)。这是最好的选择吗?
更新 2
我使用 PagedList.MVC 包实现了分页。唯一剩下的问题是 AlbumViewModel 字段是从三种不同的资源中填充的。我最初认为这只是一个性能问题,但看起来我做错了。 我得到了 5000 条记录;这是正确的吗? 谁能建议更好、更正确的方法?也许使用 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;
}
Linq 加入救援。
让我们假设这个 类 接近你的:
public class User
{
public int UserId {set; get;}
public string Username {get; set;}
}
public class Album
{
public int UserId {set; get;}
public int AlbumId {set; get;}
public string Albumname {get; set;}
}
public class Photo
{
public int AlbumId {set; get;}
public int PhotoId {set; get;}
public string Photoname {get; set;}
}
public class AlbumVM
{
public string Username {get; set;}
public string Albumname {get; set;}
public string Photoname {get; set;}
}
这将是获取结果的 Linq 表达式:
using System.Linq;
// ...
var joinAll =
users
.Join(
albumns, // joining users with albums with this 2 keys:
user=>user.UserId,
album=>album.UserId,
(user, album) => new
{
User = user,
Album = album
}
)
.Join(
photos, // joining photos with previous join with this 2 keys:
useralbum => useralbum.Album.AlbumId,
photo => photo.AlbumId,
(useralbum, photo) => new AlbumVM // generating new AlbumVM
{
Albumname = useralbum.Album.Albumname,
Username = useralbum.User.Username,
Photoname = photo.Photoname
}
);
可以随意复制粘贴 linq 并使其适应您的 类 和属性。
更多信息:
完整代码:https://gist.github.com/ctrl-alt-d/89064f253f187e255ead7421d8162dd1
我正在尝试在 MVC 5 应用程序中显示分页 table 的“相册”数据,数据值来自使用 JSONPlaceholder REST 的不同记录 API:
https://jsonplaceholder.typicode.com/
用户:(10条记录)
{
"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"
}
}
相册:(100 条记录)
{
"userId": 1,
"id": 1,
"title": "quidem molestiae enim"
}
照片:(5000 条记录)
{
"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"
}
table 将显示来自 /users、/albums 和 /photos 的字段。一些值是嵌套的,例如用户的地址值。我使用 https://json2csharp.com/ 创建了个人模型 类。接下来,我计划使用我需要的字段和 UserModel、AlbumModel 和 PhotoModel 类 的 IEnumerable 属性创建 AlbumsViewModel。我不确定如何从这些不同的资源中获取数据以及如何在 AlbumsViewModel 中表示这些实体之间的基数以呈现将显示以下内容的自定义视图:
缩略图 |标题 |名称 |电邮 | Phone |地址
查看模型:
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; }
}
更新
我已经显示了记录,但还有两个问题:
1) 有没有比使用三个嵌套循环更高效的方法?
2)如何在MVC 5中实现分页?我看过 PagedList Nuget 包(不再维护)。这是最好的选择吗?
更新 2
我使用 PagedList.MVC 包实现了分页。唯一剩下的问题是 AlbumViewModel 字段是从三种不同的资源中填充的。我最初认为这只是一个性能问题,但看起来我做错了。 我得到了 5000 条记录;这是正确的吗? 谁能建议更好、更正确的方法?也许使用 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;
}
Linq 加入救援。
让我们假设这个 类 接近你的:
public class User
{
public int UserId {set; get;}
public string Username {get; set;}
}
public class Album
{
public int UserId {set; get;}
public int AlbumId {set; get;}
public string Albumname {get; set;}
}
public class Photo
{
public int AlbumId {set; get;}
public int PhotoId {set; get;}
public string Photoname {get; set;}
}
public class AlbumVM
{
public string Username {get; set;}
public string Albumname {get; set;}
public string Photoname {get; set;}
}
这将是获取结果的 Linq 表达式:
using System.Linq;
// ...
var joinAll =
users
.Join(
albumns, // joining users with albums with this 2 keys:
user=>user.UserId,
album=>album.UserId,
(user, album) => new
{
User = user,
Album = album
}
)
.Join(
photos, // joining photos with previous join with this 2 keys:
useralbum => useralbum.Album.AlbumId,
photo => photo.AlbumId,
(useralbum, photo) => new AlbumVM // generating new AlbumVM
{
Albumname = useralbum.Album.Albumname,
Username = useralbum.User.Username,
Photoname = photo.Photoname
}
);
可以随意复制粘贴 linq 并使其适应您的 类 和属性。
更多信息:
完整代码:https://gist.github.com/ctrl-alt-d/89064f253f187e255ead7421d8162dd1