かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

ASP.NET MVCでページャーつきテーブルを表示する

WebGrid使えば何も考えなくてもしてくれるのですが、何も考えない方法だと1000件のデータを50件ずつ表示する場合でも、いったん1000件とってこないといけなくて、とっても非効率的。ページに表示する必要最低限のデータだけ用意したいというんじょが世の中の常ですよね。

ページに渡すデータの作成

Controllerで適当に作りました。

using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        private static readonly int MaxCount = 100;
        private static readonly int PageSize = 10;

        // 引数にpageという名前のパラメータを受け取るようにする。
        // WebGridのページ切り替えのリンクで押されたページ番号がくるっぽい
        public ActionResult Index(int page = 1)
        {
            var current = page * PageSize;
            if (current > MaxCount)
            {
                // ふつうはそれなりなページ返すほうがいいかな
                throw new HttpException(400, "ページ範囲外です");
            }

            // 必要なデータだけつめてページに引き渡す
            return View(new PagerViewModel
            {
                People = Enumerable
                    .Range(current, PageSize)
                    .Select(i => new Person { Name = "tanaka" + i, Age = i % 30 }),
                MaxCount = MaxCount,
                PageSize = PageSize,
                CurrentPage = page
            });
        }

    }

    public class PagerViewModel
    {
        public IEnumerable<Person> People { get; set; }
        public int MaxCount { get; set; }
        public int CurrentPage { get; set; }
        public int PageSize { get; set; }
    }

    public class Person
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }
}

WebGridでページ切り替えつきでデータを表示

WebGridのコンストラクタに表示したいデータを渡すのが一番簡単な方法ですが、今回は簡単な方法でよきにはからってくれることが邪魔なのでBindメソッドを使います。Bindメソッドを使うと、自動でページングとかをOffにできます。あとは、Controllerで設定した全体の行数とかを設定すればOK.

@{
    ViewBag.Title = "Home Page";
}
@model WebApplication1.Controllers.PagerViewModel
@{
    // WebGridを作って
    var grid = new WebGrid();
    // Bindでいろいろ指定する
    grid.Bind(
        // 表示するデータ
        source: this.Model.People,
        // 表示する列
        columnNames: new[] { "Name", "Age" },
        // 自動でやってくれるページングやソートを切る
        autoSortAndPage: false,
        // 全体の行数を設定する
        rowCount: this.Model.MaxCount);
}

<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
</div>

<div class="row">
    <div class="col-lg-12">
        @* formでくくらないとpageのパラメータが飛んでいかない *@
        @using (Html.BeginForm())
        {
            <div>
                @(this.Model.CurrentPage)Page.
            </div>
            @* あとは普通通りGetHtml *@
            @grid.GetHtml()
        }
    </div>
</div>

これで、ページ切り替えしつつ、データは必要最低限しかとらないページの完成です。