🐈

ASP.Net Core3.1 MVC/X.PagedListを用いて猫の一覧表を作成(CRUD機能無し)

8 min read

なにをする?

ASP.Net Core3.1 MVCX.PagedListを用いたユーザ一覧表とページネーションの実装

スキャフォールディング(CRUD機能を自動生成)を使えば、CRUD機能付きのユーザ一覧表を簡単に作成可能だが、今回はMVCフレームワークを理解する第一ステップとして、意図的に手動でユーザ一覧表の作成を行った。

プロジェクトのセットアップ

  • Visual Studio 2019

  • 新しいプロジェクトの作成

  • テンプレート

    • ASP.NET Core Webアプリ(Model-View-Controller)
  • プロジェクト名

    • WebApplication1
  • 場所

    • GitHubで新規リポジトリ作成
      https://github.com/ikmz0104/AspNetCoreMvc.git
    • クローンしたローカルパス
      C:\Users\username\source\repos\AspNetCoreMvc\
  • 追加情報

    • ターゲットフレームワーク:.NET Core 3.1(長期的なサポート)
    • 認証の種類:なし
    • HTTPS用の構成:✔
  • NuGetパッケージの管理

    • Microsoft.AspNetCore.Identity.EntityFrameworkCore:5.0.7
    • Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation:3.1.15
    • Microsoft.EntityFrameworkCore:5.0.7
    • Microsoft.EntityFrameworkCore.Design:5.0.7
    • Microsoft.EntityFrameworkCore.SqlServer:5.0.7
    • X.PagedList:8.1.0
    • X.PagedList Mvc.Core:8.1.0
  • .gitignoreの作成

dotnet new gitignore

ページネーション実装の準備

  • プロジェクト直下に以下のファイルを作成
    WebApplication1/PaginatedList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity
{
    public class PaginatedList<T> : List<T>
    {
        public int PageIndex { get; private set; }
        public int TotalPages { get; private set; }

        public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
        {
            PageIndex = pageIndex;
            TotalPages = (int)Math.Ceiling(count / (double)pageSize);

            this.AddRange(items);
        }

        public bool HasPreviousPage
        {
            get
            {
                return (PageIndex > 1);
            }
        }

        public bool HasNextPage
        {
            get
            {
                return (PageIndex < TotalPages);
            }
        }

        public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
        {
            var count = await source.CountAsync();
            var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
            return new PaginatedList<T>(items, count, pageIndex, pageSize);
        }
    }
}

MVC作成

  • ユーザがWebブラウザでWebアプリケーションにアクセスした際に呼び出されるController内のActionMethodがModelを参照し、抽出した値をViewに返却する(Model, View, Controllerの関係性)
  • このMVCモデルを用いて、飼い猫の一覧表を作成してみる

Model

  • DBの定義を書く

Models/CatModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace WebApplication1.Models
{
    public class CatModel
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Type { get; set; }

        public string Color { get; set; }

        public DateTime Breeding { get; set; }

        public DateTime Birth { get; set; }

    }
}

Controller

  • Modelに記載したDBをリスト化
  • リスト内の各項目、ページ番号、ページサイズの値を決定
  • ビューにリストとページ番号とページサイズを返却

Controllers/CatController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Models;
using X.PagedList;

namespace WebApplication1.Controllers
{
    public class CatController : Controller
    {
        // GET: Cat
        public ActionResult Index(int? pageIndex)
        {

            //猫の一覧表を作成
            List<CatModel> itemList = new List<CatModel>();

            CatModel tmp1 = new CatModel();
            tmp1.Id = 1;
            tmp1.Name = "CatA";
            tmp1.Type = "TypeA";
            tmp1.Breeding = new DateTime(2021, 1, 1);
            tmp1.Birth = new DateTime(2021, 1, 2);
            itemList.Add(tmp1);

            CatModel tmp2 = new CatModel();
            tmp2.Id = 2;
            tmp2.Name = "CatB";
            tmp2.Type = "TypeB";
            tmp2.Breeding = new DateTime(2021, 2, 1);
            tmp2.Birth = new DateTime(2021, 2, 2);
            itemList.Add(tmp2);

            CatModel tmp3 = new CatModel();
            tmp3.Id = 3;
            tmp3.Name = "CatC";
            tmp3.Type = "TypeC";
            tmp3.Breeding = new DateTime(2021, 3, 1);
            tmp3.Birth = new DateTime(2021, 3, 2);
            itemList.Add(tmp3);

            CatModel tmp4 = new CatModel();
            tmp4.Id = 4;
            tmp4.Name = "CatD";
            tmp4.Type = "TypeD";
            tmp4.Breeding = new DateTime(2021, 4, 1);
            tmp4.Birth = new DateTime(2021, 4, 2);
            itemList.Add(tmp4);

            CatModel tmp5 = new CatModel();
            tmp5.Id = 5;
            tmp5.Name = "CatE";
            tmp5.Type = "TypeE";
            tmp5.Breeding = new DateTime(2021, 5, 1);
            tmp5.Birth = new DateTime(2021, 5, 2);
            itemList.Add(tmp5);


            // ページ数
            int PageNumber = pageIndex ?? 1;
            // 1ページの最大表示件数
            int PageSize = 2;
            return View(itemList.ToPagedList(PageNumber, PageSize));
        }
    }
}

View

  • リスト型のモデルを受け取る
  • foreach文内でレンダリングを行い一覧表を作成
  • ページ番号の表示とクリック後のリンク発行

Views/Cat/Index.cshtml

@model IEnumerable<WebApplication1.Models.CatModel>
@using X.PagedList.Mvc.Core;
@using X.PagedList;

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "ねこ";
}

<form>
    <section>
        <h2 class="h3 mb-3">🐈</h2>
        <table class="table table-hover">
            <thead class="table-secondary ">
                <tr>
                    <th scope="col">
                        Id
                    </th>
                    <th scope="col">
                        名前
                    </th>
                    <th scope="col">
                        種類
                    </th>
                    <th scope="col">
                        飼育開始日
                    </th>
                    <th scope="col">
                        誕生日
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model)
                {
                    <tr>
                        <td>@(item.Id)</td>
                        <td>@(item.Name)</td>
                        <td>@(item.Type)</td>
                        <td>@(item.Breeding)</td>
                        <td>@(item.Birth)</td>
                    </tr>
                }
            </tbody>
        </table>

        @Html.PagedListPager(
            (IPagedList)Model,
            pageIndex => Url.Action("Index", new { pageIndex })
        )
    </section>
</form>

完成

  • 1ページ目(PageNumberは1, PageSizeが2なのでCatAとCatBの2匹)

  • 2ページ目(PageNumberは2, PageSizeが2なのでCatCとCatDの2匹)

  • 3ページ目(PageNumberは3, PageSizeが2なのでCatEのみの1匹)

参考