C# Cơ bản .NET Core §1 Cài đặt, chương trình C# đầu tiên §2 Biến, kiểu dữ liệu và nhập/xuất §3 Toán tử số học và gán §4 So sánh, logic và lệnh if, switch §5 Vòng lặp for, while §6 Phương thức - Method §7 Phương thức - Delegate §8 Lớp - Class §9 Namespace §10 Partial, Nested §11 Kiểu giá trị, tham chiếu §12 Kiểu vô danh và dynamic §13 Biểu thức lambda §14 Event §15 Hàm hủy - Quá tải toán tử - thành viên tĩnh - indexer §16 null và nullable §17 Mảng §18 Chuỗi ký tự §19 Tính kế thừa §20 Phương thức khởi tạo §21 Tính đa hình - abstract - interface §22 Struct và Enum §23 Ngoại lệ Exeption §24 IDisposable - using §25 File cơ bản §26 FileStream §27 Generic §28 Collection - List §29 SortedList §30 Queue / Stack §31 Linkedlist §32 Dictionary - HashSet §33 Phương thức mở rộng §34 ObservableCollection §35 LINQ §36 (Multithreading) async - bất đồng bộ §37 Type §38 Attribute Annotation §39 DI Dependency Injection §40 (Multithreading) Parallel §41 Thư viện lớp §42 (Networking) HttpClient §43 (Networking) HttpMessageHandler §44 (Networking) HttpListener §45 (Networking) Tcp TcpListenerr/TcpClient §46 (ADO.NET) SqlConnection §47 (ADO.NET) SqlCommand §48 (EF Core) Tổng quan §49 (EF Core) Tạo Model §50 (EF Core) Fluent API §51 (EF Core) Query §52 (EF Core) Scaffold §53 (EF Core) Migration §54 (ASP.NET CORE) Hello World! §55 (ASP.NET CORE) Middleware §56 (ASP.NET CORE) Map - Request - Response §57 (ASP.NET CORE) IServiceCollection - MapWhen §58 (ASP.NET CORE) Session - ISession §59 (ASP.NET CORE) Configuration §60 (ASP.NET CORE) Gửi Mail §61 (ASP.NET RAZOR) Khởi tạo và Route §62 (ASP.NET RAZOR) Cú pháp Razor §63 (ASP.NET RAZOR) Layout trong ASP.NET Core §64 (ASP.NET RAZOR) Partial §65 (ASP.NET RAZOR) ViewComponent §66 (ASP.NET RAZOR) TagHelper §67 (ASP.NET RAZOR) PageModel §68 (ASP.NET RAZOR) Model Binding §69 (ASP.NET RAZOR) HTML Form, Validation §70 (ASP.NET RAZOR) Upload File §71 (ASP.NET RAZOR) HtmlHelper §72 (ASP.NET RAZOR) Entity Framework §73 (ASP.NET RAZOR) Paging §74 (ASP.NET RAZOR) Identity (1) - Register, Login, Logout §75 (ASP.NET RAZOR) Identity (2) Lockout, Reset Password §76 (ASP.NET RAZOR) Identity (3) Google Login §77 (ASP.NET RAZOR) Identity (4) Facebook Login §78 (ASP.NET RAZOR) Identity (5) profile, password, email ... §79 (ASP.NET RAZOR) Identity (6) Role §80 (ASP.NET RAZOR) Identity (7) Role-based Authorization §81 (ASP.NET RAZOR) Identity (8) RoleClaim §82 (ASP.NET RAZOR) Identity (9) Authorization Handler §83 (ASP.NET RAZOR) IAuthorizationService §84 (ASP.NET MVC) Controller - View §85 (ASP.NET MVC) MVC Route

Tạo HTML phân trang sử dụng BootStrap trong ASP.NET Core

Khi hiện thị một danh sách dữ liệu dài, có nhu cầu chia nhỏ thành từng trang ngắn - cho thêm vào điều hướng để người dùng lặt trang - chuyển trang.

Ta sẽ xây dựng một Partial hiện thị thanh điều hướng này theo dữ liệu gửi đến. Giả thiết đầu vào phát sinh HTML sẽ gồm các dữ liệu sau:

  • countPages - số nguyên - là tổng số trang của dữ liệu
  • currentPage - số nguyên - trang hiện tại
  • generateUrl - là một delegate - Func<int p, string url> nhận thao số p là chỉ mục trang trả về chuỗi là Url của trang. Ví dụ p = 5 trả về /product/?page=5 - delegate này phát sinh Url theo Page, Controller ... như thế nào là do bạn xây dựng khi truyền tham số. Xem thêm Action và Func

Nội dung của Partial __Paging.cshtml sẽ lưu ở Pages/Shared/_Paging.cshtml

@model dynamic
@{
    int currentPage  = Model.currentPage;
    int countPages   = Model.countPages;
    var generateUrl  = Model.generateUrl;
    
    if (currentPage > countPages)
        currentPage = countPages;

    if (countPages <= 1) return;
    

    int? preview = null;
    int? next = null;

    if (currentPage > 1)
        preview = currentPage - 1;

    if (currentPage < countPages)
        next = currentPage + 1;

    // Các trang hiện thị trong điều hướng
    List<int> pagesRanges = new List<int>();    

        
    int delta       = 5;             // Số trang mở rộng về mỗi bên trang hiện tại     
    int remain     = delta * 2;      // Số trang hai bên trang hiện tại
    pagesRanges.Add(currentPage);
    // Các trang phát triển về hai bên trang hiện tại
    for (int i = 1; i <= delta; i++)
    {
        if (currentPage + i  <= countPages) {
            pagesRanges.Add(currentPage + i); 
            remain --;
        }
               
        if (currentPage - i >= 1) {
            pagesRanges.Insert(0, currentPage - i);
            remain --;
        }
            
    }    
    // Xử lý thêm vào các trang cho đủ remain (xảy ra ở đầu mút của khoảng trang không đủ
    // trang chèn  vào)
    if (remain > 0) {
        if (pagesRanges[0] == 1) {
            for (int i = 1; i <= remain; i++)
            {
                if (pagesRanges.Last() + 1 <= countPages) {
                    pagesRanges.Add(pagesRanges.Last() + 1);
                }
            }
        }
        else {
            for (int i = 1; i <= remain; i++)
            {
                if (pagesRanges.First() - 1 > 1) {
                    pagesRanges.Insert(0, pagesRanges.First() - 1);
                }
            }
        }
    }

}


<ul class="pagination">
<!-- Previous page link -->
@if (preview != null)
{
    <li class="page-item">
        <a class="page-link" href="@generateUrl(preview)">Trang trước</a>
    </li>
}
else
{
    <li class="page-item disabled">
        <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Trang trước</a>
    </li>
}
   
<!-- Numbered page links -->
@foreach (var pageitem in pagesRanges)
{
    if (pageitem != currentPage) {
        <li class="page-item">
            <a class="page-link" href="@generateUrl(pageitem)">
                @pageitem
            </a>
        </li>
    }   
    else 
    {
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="#">@pageitem <span class="sr-only">(current)</span></a>
        </li>
    }
}


<!-- Next page link -->
@if (next != null)
{
    <li class="page-item">
        <a class="page-link" href="@generateUrl(next)">Trang sau</a>
    </li>
}
else 
{
    <li class="page-item disabled">
        <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Trang sau</a>
    </li>
}
</ul>

Bất kỳ khi nào muốn chèn HTML phân trang bạn có thể chèn bằng cách dùng

<partial name="_Paging" model="@datapaging" />

Trong đó datapagingkiểu dynamic chứa các thông số cần truyền vào partial gồm: currentPage, currentPage, generateUrl

Ví dụ chạy thử trong một Razor Page:

@{
    // xây dựng Func phát sinh Url từ page ./Index
    Func<int?,string> generateUrl = (int? _pagenumber)  => {
        return Url.Page("./User", new {pageNumber = _pagenumber});
    };

    var datapaging = new {
        currentPage = 2,    // trang hiện tại
        countPages  = 20,   // tổng  số trang 
        generateUrl =  generateUrl
    };

}
<partial name="_Paging" model="@datapaging" />

Kết quả như sau:

role

Khi sử dụng thực tế các tham số countPages, currentPage được truyền đến từ PageModel, Controller thường là kết quả tính toán dựa trên truy vấn số lượng phần tử cần hiện thị từ một bảng dữ liệu

Kỹ thuật truy vấn LINQ lấy số phần tử từng trang

Khi bạn viết một câu truy vấn LINQ ví dụ:

var products = from p in dbproducts select p;

Trong đó dbproducts là nguồn cấp dữ liệu nào đó, ví dụ DbSet trong DbContext ..., thì products là một đối tượng kiểu IQueryable, bạn có thể bỏ qua một số phần từ đầu chỉ lấy các phần tử sau bằng cách dùng Skip(n), bạn chỉ lấy ra một số phần tử bằng cách dùng Take(n)

Ví dụ, bỏ qua 100 phần tử đầu tiên, tiếp theo chỉ lấy ra 10 phần tử thì bạn viết

var pros = products.Skip(100).Take(10);

Bạn có thể áp dụng kỹ thật này để lấy ra số phần tử theo từng trang

var products = from p in dbproducts select p;

// Lấy tổng số dòng dữ liệu
var totalItems = products.Count();
// Tính số trang hiện thị (mỗi trang hiện thị ITEMS_PER_PAGE mục do bạn cấu hình = 10, 20 ...)
int totalPages = (int)Math.Ceiling((double)totalItems / ITEMS_PER_PAGE);
// Lấy phần tử trong  hang hiện tại (pageNumber là trang hiện tại - thường Binding từ route)
var pros = products.Skip(ITEMS_PER_PAGE * (pageNumber - 1)).Take(ITEMS_PER_PAGE).ToList();

Code trên có thể viết trong Controller, PageModel ... bạn có được trang hiện tại, tổng số trang, các phần tử của trang hiện tại để chuyển cho View - hiện thị phần tử và tạo HTML Paging

Đăng ký theo dõi ủng hộ kênh