programing

ASP.NET MVC에서 페이지화를 수행하려면 어떻게 해야 합니까?

linuxpc 2023. 6. 10. 08:29
반응형

ASP.NET MVC에서 페이지화를 수행하려면 어떻게 해야 합니까?

ASP.NET MVC에서 페이지화를 수행하는 가장 선호되고 쉬운 방법은 무엇입니까?즉, 목록을 검색 가능한 여러 페이지로 나누는 가장 쉬운 방법은 무엇입니까?

예를 들어 데이터베이스/게이트웨이/리포지토리에서 다음과 같은 요소 목록을 가져옵니다.

public ActionResult ListMyItems()
{
    List<Item> list = ItemDB.GetListOfItems();
    ViewData["ItemList"] = list;

    return View();
}

간단히 설명하기 위해 내 작업에 대한 페이지 번호를 매개 변수로 지정하고 싶습니다.다음과 같이:

public ActionResult ListMyItems(int page)
{
   //...
}

그럼, 데이터 소스는 무엇입니까?작업에는 몇 가지 기본 인수가 사용될 수 있습니다.

ActionResult Search(string query, int startIndex, int pageSize) {...}

시작할 수 있도록 경로 설정에서 기본값입니다.인덱스는 0이고 pageSize는 20입니다.

        routes.MapRoute("Search", "Search/{query}/{startIndex}",
                        new
                        {
                            controller = "Home", action = "Search",
                            startIndex = 0, pageSize = 20
                        });

피드를 분할하려면 LINQ를 매우 쉽게 사용할 수 있습니다.

var page = source.Skip(startIndex).Take(pageSize);

(또는 "startIndex"가 아닌 "pageNumber"를 사용하는 경우 곱셈을 수행합니다.)

LINQ-to-SQL, EF 등을 사용하면 데이터베이스에도 "합성"됩니다.

그런 다음 다음 다음 페이지(등)에 대한 작업 링크를 사용할 수 있습니다.

<%=Html.ActionLink("next page", "Search", new {
                query, startIndex = startIndex + pageSize, pageSize }) %>

저는 프런트 엔드로 이를 수행하는 간단한 방법도 다루고 싶었습니다.

컨트롤러:

public ActionResult Index(int page = 0)
{
    const int PageSize = 3; // you can always do something more elegant to set this

    var count = this.dataSource.Count();

    var data = this.dataSource.Skip(page * PageSize).Take(PageSize).ToList();

    this.ViewBag.MaxPage = (count / PageSize) - (count % PageSize == 0 ? 1 : 0);

    this.ViewBag.Page = page;

    return this.View(data);
}

보기:

@* rest of file with view *@

@if (ViewBag.Page > 0)
{
    <a href="@Url.Action("Index", new { page = ViewBag.Page - 1 })" 
       class="btn btn-default">
        &laquo; Prev
    </a>
}
@if (ViewBag.Page < ViewBag.MaxPage)
{
    <a href="@Url.Action("Index", new { page = ViewBag.Page + 1 })" 
       class="btn btn-default">
        Next &raquo;
    </a>
}

저도 같은 문제를 겪었고 호출기 클래스를 위한 매우 우아한 솔루션을 찾았습니다.

http://blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc/

컨트롤러에서 통화 내용은 다음과 같습니다.

return View(partnerList.ToPagedList(currentPageIndex, pageSize));

그리고 당신이 보기에:

<div class="pager">
    Seite: <%= Html.Pager(ViewData.Model.PageSize, 
                          ViewData.Model.PageNumber,
                          ViewData.Model.TotalItemCount)%>
</div>

여기 제가 이것을 하는데 도움이 된 링크가 있습니다.

페이지 목록을 사용합니다.MVC NuGet 패키지.다음 단계를 요약해 보겠습니다.

  1. 페이지 목록을 설치합니다.MVC NuGet 패키지

  2. 프로젝트 빌드

  3. 더하다 using PagedList; 관리자에게

  4. 설정 페이지로 작업 수정 public ActionResult ListMyItems(int? page) { List list = ItemDB.GetListOfItems(); int pageSize = 3; int pageNumber = (page ?? 1); return View(list.ToPagedList(pageNumber, pageSize)); }

  5. 보기 하단에 페이징 링크 추가 @*Your existing view*@ Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount @Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))

컨트롤러

 [HttpGet]
    public async Task<ActionResult> Index(int page =1)
    {
        if (page < 0 || page ==0 )
        {
            page = 1;
        }
        int pageSize = 5;
        int totalPage = 0;
        int totalRecord = 0;
        BusinessLayer bll = new BusinessLayer();
        MatchModel matchmodel = new MatchModel();
        matchmodel.GetMatchList = bll.GetMatchCore(page, pageSize, out totalRecord, out totalPage);
        ViewBag.dbCount = totalPage;
        return View(matchmodel);
    }

비즈니스 로직

  public List<Match> GetMatchCore(int page, int pageSize, out int totalRecord, out int totalPage)
    {
        SignalRDataContext db = new SignalRDataContext();
        var query = new List<Match>();
        totalRecord = db.Matches.Count();
        totalPage = (totalRecord / pageSize) + ((totalRecord % pageSize) > 0 ? 1 : 0);
        query = db.Matches.OrderBy(a => a.QuestionID).Skip(((page - 1) * pageSize)).Take(pageSize).ToList();
        return query;
    }

총 페이지 수를 표시하기 위한 보기

 if (ViewBag.dbCount != null)
    {
        for (int i = 1; i <= ViewBag.dbCount; i++)
        {
            <ul class="pagination">
                <li>@Html.ActionLink(@i.ToString(), "Index", "Grid", new { page = @i },null)</li> 
            </ul>
        }
    }

ASP.NET MVC 응용 프로그램에서 페이지 목록을 만드는 가장 쉬운 방법은 페이지 목록 라이브러리를 사용하는 것이라고 생각합니다.

다음 github 저장소에 완전한 예가 있습니다.도움이 되길 바랍니다.

public class ProductController : Controller
{
    public object Index(int? page)
    {
        var list = ItemDB.GetListOfItems();

        var pageNumber = page ?? 1; 
        var onePageOfItem = list.ToPagedList(pageNumber, 25); // will only contain 25 items max because of the pageSize

        ViewBag.onePageOfItem = onePageOfProducts;
        return View();
    }
}

데모 링크: http://ajaxpagination.azurewebsites.net/

소스 코드: https://github.com/ungleng/SimpleAjaxPagedListAndSearchMVC5

독립체

public class PageEntity
{
    public int Page { get; set; }
    public string Class { get; set; }
}

public class Pagination
{
    public List<PageEntity> Pages { get; set; }
    public int Next { get; set; }
    public int Previous { get; set; }
    public string NextClass { get; set; }
    public string PreviousClass { get; set; }
    public bool Display { get; set; }
    public string Query { get; set; }
}

HTML

<nav>
    <div class="navigation" style="text-align: center">
        <ul class="pagination">
            <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@Model.Previous+@Model.Query)">&laquo;</a></li>
            @foreach (var item in @Model.Pages)
            {
                <li class="page-item @item.Class"><a class="page-link" href="?page=@(item.Page+@Model.Query)">@item.Page</a></li>
            }
            <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@Model.Next+@Model.Query)">&raquo;</a></li>
        </ul>
    </div>
 </nav>

페이징 로직

public Pagination GetCategoryPaging(int currentPage, int recordCount, string query)
{
    string pageClass = string.Empty; int pageSize = 10, innerCount = 5;

    Pagination pagination = new Pagination();
    pagination.Pages = new List<PageEntity>();
    pagination.Next = currentPage + 1;
    pagination.Previous = ((currentPage - 1) > 0) ? (currentPage - 1) : 1;
    pagination.Query = query;

    int totalPages = ((int)recordCount % pageSize) == 0 ? (int)recordCount / pageSize : (int)recordCount / pageSize + 1;

    int loopStart = 1, loopCount = 1;

    if ((currentPage - 2) > 0)
    {
        loopStart = (currentPage - 2);
    }

    for (int i = loopStart; i <= totalPages; i++)
    {
        pagination.Pages.Add(new PageEntity { Page = i, Class = string.Empty });

        if (loopCount == innerCount)
        { break; }

        loopCount++;
    }

    if (totalPages <= innerCount)
    {
        pagination.PreviousClass = "disabled";
    }

    foreach (var item in pagination.Pages.Where(x => x.Page == currentPage))
    {
        item.Class = "active";
    }

    if (pagination.Pages.Count() <= 1)
    {
        pagination.Display = false;
    }

    return pagination;
}

컨트롤러 사용

public ActionResult GetPages()
{
    int currentPage = 1; string search = string.Empty;
    if (!string.IsNullOrEmpty(Request.QueryString["page"]))
    {
        currentPage = Convert.ToInt32(Request.QueryString["page"]);
    }

    if (!string.IsNullOrEmpty(Request.QueryString["q"]))
    {
        search = "&q=" + Request.QueryString["q"];
    }
    /* to be Fetched from database using count */
    int recordCount = 100;

    Place place = new Place();
    Pagination pagination = place.GetCategoryPaging(currentPage, recordCount, search);

    return PartialView("Controls/_Pagination", pagination);
}
public ActionResult Paging(int? pageno,bool? fwd,bool? bwd)        
{
    if(pageno!=null)
     {
       Session["currentpage"] = pageno;
     }

    using (HatronEntities DB = new HatronEntities())
    {
        if(fwd!=null && (bool)fwd)
        {
            pageno = Convert.ToInt32(Session["currentpage"]) + 1;
            Session["currentpage"] = pageno;
        }
        if (bwd != null && (bool)bwd)
        {
            pageno = Convert.ToInt32(Session["currentpage"]) - 1;
            Session["currentpage"] = pageno;
        }
        if (pageno==null)
        {
            pageno = 1;
        }
        if(pageno<0)
        {
            pageno = 1;
        }
        int total = DB.EmployeePromotion(0, 0, 0).Count();
        int  totalPage = (int)Math.Ceiling((double)total / 20);
        ViewBag.pages = totalPage;
        if (pageno > totalPage)
        {
            pageno = totalPage;
        }
        return View (DB.EmployeePromotion(0,0,0).Skip(GetSkip((int)pageno,20)).Take(20).ToList());     
    }
}

private static int GetSkip(int pageIndex, int take)
{
    return (pageIndex - 1) * take;
}

@model IEnumerable<EmployeePromotion_Result>
@{
  Layout = null;
}

 <!DOCTYPE html>

 <html>
 <head>
    <meta name="viewport" content="width=device-width" />
    <title>Paging</title>
  </head>
  <body>
 <div> 
    <table border="1">
        @foreach (var itm in Model)
        {
 <tr>
   <td>@itm.District</td>
   <td>@itm.employee</td>
   <td>@itm.PromotionTo</td>
 </tr>
        }
    </table>
    <a href="@Url.Action("Paging", "Home",new { pageno=1 })">First  page</a> 
    <a href="@Url.Action("Paging", "Home", new { bwd =true })"><<</a> 
    @for(int itmp =1; itmp< Convert.ToInt32(ViewBag.pages)+1;itmp++)
   {
       <a href="@Url.Action("Paging", "Home",new { pageno=itmp   })">@itmp.ToString()</a>
   }
    <a href="@Url.Action("Paging", "Home", new { fwd = true })">>></a> 
    <a href="@Url.Action("Paging", "Home", new { pageno =                                                                               Convert.ToInt32(ViewBag.pages) })">Last page</a> 
</div>
   </body>
  </html>

재사용 가능한 페이지를 만들 수 있습니다.필요한 것은 다음과 같습니다.

  • 페이지 수 및 페이지에 대한 링크를 저장하는 부분 보기
  • 페이지 논리를 포함하는 재사용 가능한 메서드IQueryable

소스 코드의 전체 예는 여기에서 확인할 수 있습니다.

그래서 우리의 코드는 이것을 참조하십시오.

사용자 테이블.SQL Server를 사용해 본 적이 있습니다.

IF NOT EXISTS 
(
    SELECT 1
    FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Person'
    AND TABLE_SCHEMA = 'dbo'
)
BEGIN
    CREATE TABLE dbo.Person 
    (
          ID                 INT                 IDENTITY(1, 1) NOT NULL PRIMARY KEY
        , CreateDate         DATETIME            NOT NULL DEFAULT GETDATE()
        , Creator            VARCHAR(100)        NOT NULL
        , ModifyDate         DATETIME            NULL
        , Modifier           VARCHAR(20)         NULL

        , FirstName          VARCHAR(150)        NOT NULL
        , LastName           VARCHAR(1000)       NOT NULL        
    )
ON [PRIMARY]
END
GO

DatabaseFirst 접근법을 사용했습니다.엔티티 프레임워크에서 생성한 클래스입니다.

public partial class Person
{
    public int ID { get; set; }
    public System.DateTime CreateDate { get; set; }
    public string Creator { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Nullable<System.DateTime> ModifyDate { get; set; }
    public string Modifier { get; set; }
}

다음은 데이터 및 페이지 정보를 포함하는 클래스입니다.

public class DataResultViewModel<T>
{
    /// <summary>
    /// Data items
    /// </summary>
    public IEnumerable<T> Items { get; set; }

    /// <summary>
    /// Pagination
    /// </summary>
    public Pagination Pagination { get; set; }
}

이것은 사람에 대한 정보를 포함하는 클래스입니다.

public class PersonViewModel
{
    public int ID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}


/// <summary>
/// What route should be requested while paging
/// </summary>
public class RouteInfo
{
    /// <summary>
    /// Name of controller
    /// </summary>
    public string ControllerName { get; set; }

    /// <summary>
    /// Name of action
    /// </summary>
    public string ActionName { get; set; }
}

및 페이지화 클래스:

public class Pagination
{
    /// <summary>
    /// Total count of items
    /// </summary>
    public int TotalItems { get; set; }

    /// <summary>
    /// Count of items at the page
    /// </summary>
    public int PageSize { get; set; } = 5;

    /// <summary>
    /// Current page
    /// </summary>
    public int Page { get; set; }

    /// <summary>
    /// Sorted by field name
    /// </summary>
    public string SortBy { get; set; }

    /// <summary>
    /// Is this an ascending sort?
    /// </summary>
    public bool IsSortAscending { get; set; }

    /// <summary>
    /// Information about what page should be requested
    /// </summary>
    public RouteInfo RouteInfo { get; set; }
}

그리고 페이지를 만드는 수업.기적으로본,Skip() Take .()는 이 .IQueryable그리고 C#은 확장 방법이라고 불리는 매우 깔끔한 기능을 가지고 있습니다.확장 메서드에서 코드를 재사용할 수 있습니다.

public static class IQueryableExtension
{
    public static IQueryable<T> UseOrdering<T, TResultSelector>(this IQueryable<T> query, 
        Pagination pagination,
             Expression<Func<T, TResultSelector>> field)
    {
        if (string.IsNullOrWhiteSpace(pagination.SortBy) 
            || string.IsNullOrEmpty(pagination.SortBy))
            return query;

        return pagination.IsSortAscending ?
            query.OrderBy(field) :
            query.OrderByDescending(field);
    }

    public static IQueryable<T> UsePagination<T>(this IQueryable<T> query, 
        Pagination pagination)
    {
        if (pagination.Page <= 0)
            pagination.Page = 1;

        if (pagination.PageSize <= 0)
            pagination.PageSize = 10;

         return query.Skip((pagination.Page - 1) * pagination.PageSize)
             .Take(pagination.PageSize);
    }
}

다음은 서비스 계층의 클래스입니다.

public class PersonService
{
    public DataResultViewModel<PersonViewModel> GetWithPagination(Pagination pagination,
        Expression<Func<Person, DateTime>> fieldName)
    {
        var result = new DataResultViewModel<PersonViewModel>();

        using (var db = new MiscellaneousEntities())
        {
            var persons = db.Person.AsQueryable();

            result.Pagination = pagination;
            result.Pagination.TotalItems = persons.Count();
            result.Pagination.RouteInfo = new RouteInfo() 
            {
                ActionName = "Index", 
                ControllerName = "Person"
            };

            if (pagination.SortBy == null)
                pagination.SortBy = "CreateDate";
            persons = persons.UseOrdering(pagination, fieldName);
            persons = persons.UsePagination(pagination);

            result.Items = persons
                .Select(s => new PersonViewModel()
                {
                    ID = s.ID,
                    FirstName = s.FirstName,
                    LastName = s.LastName
                })
                .ToList();

             return result;
        }
    }
}

그리고 사람의 통제자:

public class PersonController : Controller
{
    PersonService _personService;

    public PersonController()
    {
        _personService = new PersonService();
    }

    // GET: Person
    public ActionResult Index(int? page, int? pageSize, string sortBy,
        bool? isSortAscending)
    {
        return View
            (_personService.GetWithPagination(new Pagination()
                {
                    Page = page ?? 1,
                    PageSize = pageSize ?? 3,
                    SortBy = sortBy,
                    IsSortAscending = isSortAscending ?? false
                },
                v => v.CreateDate
                )
            );
    }
}

그러면 우리는 뷰를 만들어야 합니다.

페이지를 지정해야 하는 사용자 보기입니다.

@model  OnlyPagination.ViewModel.DataResultViewModel<OnlyPagination.ViewModel.PersonViewModel>

<div class="d-flex justify-content-center">
    <div>
        @foreach (var item in Model.Items)
        {
            <div>
                <p>Id is @item.ID</p>
                <p>FirstName is @item.FirstName</p>
                <p>LastName is @item.LastName</p>
            </div>
            <hr />
        }
    </div>
</div>

<div class="d-flex justify-content-center">
    @{
        @Html.Partial("Pagination", Model.Pagination)
    }
</div>

재사용 가능한 페이지 분할 보기입니다.

@model OnlyPagination.Extensions.Query.Model.Pagination

@{
    var pagesCount = Math.Ceiling((decimal)Model.TotalItems / (decimal)Model.PageSize);
    var pages = new List<int>();

    for (var i = 1; i <= pagesCount; i++)
    {
        pages.Add(i);
    }
}

<div>
    <p class="d-flex justify-content-center">Page @Model.Page of @pagesCount</p>

    <ul class="pagination">
        <li class="page-item @( Model.Page == 1 ? "disabled" : "" )">
            <a aria-label="Previous" class="page-link"
                href="@Url.Action
                (Model.RouteInfo.ActionName, Model.RouteInfo.ControllerName,
                new { page = Model.Page - 1, pageSize = Model.PageSize })">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>

        @for (int pageNumber = 1; pageNumber <= pages.Count; pageNumber++)
        {
            <li class="page-item @( Model.Page == pageNumber ? "active" : "" )">
                <a class="page-link"
                    href="@Url.Action(Model.RouteInfo.ActionName, 
                        Model.RouteInfo.ControllerName,
                        new { page = pageNumber, pageSize = Model.PageSize })"> 
                        @pageNumber </a>
                </li>
            }

        <li class="page-item @(Model.Page == pages.Count ? "disabled" : "")">
            <a aria-label="Next" class="page-link"
                href="@Url.Action
                      (Model.RouteInfo.ActionName, Model.RouteInfo.ControllerName,
                      new { page = Model.Page + 1, pageSize = Model.PageSize })">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</div>

그게 다야!

페이지 페이지를 삽입할 ASP .NET 응용 프로그램에서 먼저 페이지 목록 및 페이지 목록을 설치해야 합니다.프로젝트에 대한 NuGet 패키지의 MVC.

그리고 데이터베이스에서 책 목록을 반환하는 샘플 방법을 포함했습니다.그리고 각 페이지에 4개의 항목을 표시하기 위해 페이지 페이지를 포함했습니다.

public ActionResult Books(int? i)
    {
        IEnumerable<Books> BooksList;
        HttpResponseMessage response = GlobalVariables.webApiClient.GetAsync("Tbl_Books").Result;
        BooksList = response.Content.ReadAsAsync<IEnumerable<Books>>().Result;
        return View(BooksList.ToList().ToPagedList(i ?? 1, 4));
    }

보기 페이지에서 이 항목을 포함해야 합니다.

@Html.PagedListPager(Model, i => Url.Action("Books", "Library", new { i }))

언급URL : https://stackoverflow.com/questions/446196/how-do-i-do-pagination-in-asp-net-mvc

반응형