使用 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