使用自定义HtmlHelpers在.NET Core MVC应用程序中实现分页
如何在.NET Core MVC应用程序中构建自定义HtmlHelpers以提供分页功能
引言
在本文中,我们将尝试构建自定义HtmlHelper
,以在.NET Core MVC应用程序中提供分页功能。
本文假定用户具备HtmlHelper
的基本知识。
对于不了解HTML helpers的读者,这里有一个简短的解释。
- HTML helpers使开发人员能够轻松快速地创建HTML页面。
- 在大多数情况下,HTML helper只是一个返回
string
的方法。 - MVC附带内置的HTML helpers,如
@Html.TextBox()
、@Html.CheckBox()
、@Html.Label
等。 Htmlhelper
在razor视图中渲染HTML控件。例如,@Html.TextBox()
渲染<input type="textbox">
控件,@Html.CheckBox()
渲染<input type="checkbox">
控件,等等。
请查阅Microsoft关于HTML helpers的文档。
背景
在Web应用程序中,如果要显示大量记录,则需要提供分页。在本文中,我们通过简单地创建一个自定义HtmlHelper
来实现.NET Core MVC应用程序中的分页。为了保持简单,我们只使用数字来表示数据。
假设我们需要在多个页面上显示55条记录,每页10条。我们可以将所有项目显示在6个页面上,如下图所示。在实际应用中,数据可能是从数据库、文件等获取的记录数量。
让我们看看如何做到这一点。
- 打开Visual Studio 2019 > 创建.NET Core MVC应用程序,如下图所示
- 将项目命名为
HTMLHelpersApp
。 - 选择.NET Framework版本
- 首先,让我们创建所需的模型和助手文件。
- 创建一个新的模型“
Number
”。- 右键单击Model文件夹,然后添加“
Number
”类
- 右键单击Model文件夹,然后添加“
- 创建一个新的模型“
- 在Number.cs中添加代码。此模型捕获用户输入。它只有一个属性“
InputNumber
”。using System; using System.ComponentModel.DataAnnotations; namespace HTMLHelpersApp.Models { public class Number { //validation for required, only numbers, allowed range-1 to 500 [Required(ErrorMessage = "Value is Required!. Please enter value between 1 and 500.")] [RegularExpression(@"^\d+$", ErrorMessage = "Only numbers are allowed. Please enter value between 1 and 500.")] [Range(1, 500, ErrorMessage = "Please enter value between 1 and 500.")] public int InputNumber = 1; } }
- 现在让我们添加一个通用类PageInfo.cs。创建新文件夹
Common
并添加PageInfo.cs类。- 右键单击项目文件夹,然后添加一个新文件夹
- 在PageInfo.cs中添加代码
- Page Start表示当前页的第一项。
- Page End表示当前页的最后一项。
- Items per page表示每页显示的项数。
- Last Page表示页数/最后一页的页码。
- Total Items表示项目的总数。
根据总项目数和每页项目数,可以计算出总页数、每页的第一个项目和最后一个项目。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace HTMLHelpersApp.Common { public class PageInfo { public int TotalItems { get; set; } public int ItemsPerPage { get; set; } public int CurrentPage { get; set; } public PageInfo() { CurrentPage = 1; } //starting item number in the page public int PageStart { get { return ((CurrentPage - 1) * ItemsPerPage + 1); } } //last item number in the page public int PageEnd { get { int currentTotal = (CurrentPage - 1) * ItemsPerPage + ItemsPerPage; return (currentTotal < TotalItems ? currentTotal : TotalItems); } } public int LastPage { get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); } } } }
- 现在我们来看最重要的一部分,即创建自定义
Htmlhelper
。- 创建自定义
Htmlhelper PageLink
,它渲染页码、上一页和下一页链接。 - 在“Common”文件夹中添加一个新类“PagingHtmlHelpers.cs”。
- 创建自定义
- 在“PagingHtmlHelpers.cs”中添加代码
- 扩展
HtmlHelper
类并添加新功能以添加Page链接public static IHtmlContent PageLinks(this IHtmlHelper htmlHelper, PageInfo pageInfo, Func<int, string> PageUrl)
- 接受两个参数
pageInfo
- 添加页码
- 委托给一个接受整数和字符串作为参数的函数
- 添加控制器操作方法所需的参数
- 使用TagBuilder创建anchor标签
TagBuilder tag = new TagBuilder("a");
- 添加属性
tag.MergeAttribute("href", hrefValue);
tag.InnerHtml.Append(" "+ innerHtml + " ");
- 样式也可以作为属性应用。
using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Rendering; using System; using System.Text; namespace HTMLHelpersApp.Common { public static class PagingHtmlHelpers { public static IHtmlContent PageLinks (this IHtmlHelper htmlHelper, PageInfo pageInfo, Func<int, string> PageUrl) { StringBuilder pagingTags = new StringBuilder(); //Prev Page if (pageInfo.CurrentPage > 1) { pagingTags.Append(GetTagString ("Prev", PageUrl(pageInfo.CurrentPage - 1))); } //Page Numbers for (int i = 1; i <= pageInfo.LastPage; i++) { pagingTags.Append(GetTagString(i.ToString(), PageUrl(i))); } //Next Page if (pageInfo.CurrentPage < pageInfo.LastPage) { pagingTags.Append(GetTagString ("Next", PageUrl(pageInfo.CurrentPage + 1))); } //paging tags return new HtmlString(pagingTags.ToString()); } private static string GetTagString(string innerHtml, string hrefValue) { TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag tag.MergeAttribute("class","anchorstyle"); tag.MergeAttribute("href", hrefValue); tag.InnerHtml.Append(" "+ innerHtml + " "); using (var sw = new System.IO.StringWriter()) { tag.WriteTo(sw, System.Text.Encodings.Web.HtmlEncoder.Default); return sw.ToString(); } } } }
- 扩展
- 在“Models”文件夹中添加一个新类“ShowPaging.cs”。
DisplayResult
将显示每页的数字列表PageInfo
将捕获所有页面详情,如页数、总项目数、每页的起始项和结束项等。
using HTMLHelpersApp.Common; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace HTMLHelpersApp.Models { public class ShowPaging { //validation for required, only numbers, allowed range-1 to 500 [Required(ErrorMessage = "Value is Required!. Please enter value between 1 and 500.")] [RegularExpression(@"^\d+$", ErrorMessage = "Only positive numbers are allowed. Please enter value between 1 and 500.")] [Range(1, 500, ErrorMessage = "Please enter value between 1 and 500.")] public int InputNumber { get; set; } public List<string> DisplayResult { get; set; } public PageInfo PageInfo; } }
- 现在我们有了所需的模型和助手,让我们来创建控制器和视图。
- 添加一个新的控制器 - “
HTMLHelperController
”。- 右键单击controller文件夹,然后在上下文菜单中选择Controller。
- 右键单击controller文件夹,然后在上下文菜单中选择Controller。
- 选择“MVCController-Empty”。
- 在“
HTMLHelperController
”中添加代码- Number操作用于用户输入数字
- ShowPaging操作用于在多个页面上显示数据
- 当点击页面链接时调用
using HTMLHelpersApp.Common; using HTMLHelpersApp.Models; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; namespace HTMLHelpersApp.Controllers { public class HTMLHelperController : Controller { private const int PAGE_SIZE = 10; public IActionResult Number() { return View(); } public IActionResult ShowPaging(ShowPaging model, int page = 1, int inputNumber = 1) { if (ModelState.IsValid) { var displayResult = new List<string>(); string message; //set model.pageinfo model.PageInfo = new PageInfo(); model.PageInfo.CurrentPage = page; model.PageInfo.ItemsPerPage = PAGE_SIZE; model.PageInfo.TotalItems = inputNumber; //Set model.displayresult - numbers list for (int count = model.PageInfo.PageStart; count <= model.PageInfo.PageEnd; count++) { message = count.ToString(); displayResult.Add(message.Trim()); } model.DisplayResult = displayResult; } //return view model return View(model); } } }
- 当点击页面链接时调用
- 在Views文件夹中创建一个新文件夹“HTMLHelper”
- 遵循上面提到的相同步骤添加新文件夹。
- 创建一个新视图“Number.cshtml”
- 右键单击Views > HTMLHelper文件夹并添加一个新视图。
- 在“Number.cshtml”中添加代码
@model HTMLHelpersApp.Models.Number <h4>Number</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="ShowPaging" method="get"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <input asp-for="InputNumber" class="form-control"/> </div> <div class="form-group"> <input type="submit" value="Submit" class="btn btn-primary" /> </div> </form> </div> </div>
- 同样,创建一个新视图“ShowPaging.cshtml”
- 遵循上面提到的相同步骤
- 在“ShowPaging.cshtml”中添加代码
@model HTMLHelpersApp.Models.ShowPaging @using HTMLHelpersApp.Common <link rel="stylesheet" href ="~/css/anchorstyles.css"/> <form> <h4>Show Paging</h4> <hr /> <div asp-validation-summary="All" class="text-danger"></div> <dl class="row"> <dt class="col-sm-2"> <b>Number: </b> @Html.DisplayFor(model => model.InputNumber) </dt> <dd> <a asp-action="Number">Change Number</a> </dd> </dl> <div> @if (Model != null && Model.DisplayResult != null) { <ul> @foreach (var item in Model.DisplayResult) { <li>@Html.Raw(item)</li> } </ul> <div> @Html.PageLinks(@Model.PageInfo, x => Url.Action("ShowPaging", new { page = x.ToString(), inputNumber = @Model.InputNumber })) </div> } </div> </form>
注意:
@Html.PageLinks
是自定义HttpHelper
。 - 解决方案资源管理器将如下所示
- 我们已经添加了所有必需的文件。在运行之前,让我们在“startup.cs”中配置默认控制器和操作。
- 编译并运行应用程序。
- 输入数字
35
。 - 点击Submit
- 您会在底部看到分页。每页显示10个数字。因此,将有4页来显示35个数字。点击页面2链接以查看第二页。
- 您可以根据需要为页面链接应用样式。
历史
- 2022年2月13日:初始版本