第66章 基于.Net(Core)x框架的开源分页插件

1 Jquery DataTable 分页插件

    Jquery DataTable分页插件是完全基于javaScript的,所以它是跨框架的,即不管你使用的是那种语言,那种平台开发网站程序,基本上都能通过使用Jquery DataTable分页插件实现分页操作。

    在nopCommerce开发者通过后台代码对Jquery DataTable分页插件的分页操作前后台实现都进行了重构定义,因此nopCommerce程序中Jquery DataTable分页插件的实现与nopCommerce程序的耦合十分紧密,所的它的独立性极差,从而造成了它只能用于学习,而不能在其它程序中以及其快速和低廉的代价进行移值和复用。

    下面我将大家介绍两个能够快速和低廉的代价进行移值和复用的并基于.Net(Core)x框架的开源分页插件,即这个两分页插件只能用于基于.Net(Core)x框架开发的Web程序,如果大家有更好的选择请在评论区留言。

2 MvcCorePager 分页插件

   我最早接触的开源分页插件就是杨涛的AspNetPager分页控件(当前版本:7.5.1),该分页控件是基于.Net Framework框架的,同时由于该控件的最后版本的更构日期为:2015-6-9,所以该插件已经适合集成到在当前的程序中实现分页操作,但不可否认的是AspNetPager分页控件是我当前所知的使用最为傻瓜,移值和复用最为快速和低廉的分页插件。所以作为对Jquery DataTable分页插件的替代,我最早查看的就是杨涛的MvcCorePager分页控件,但是它与的AspNetPager分页控件相比差距巨大,虽然它的最后提交日期为:22-5-27,但是当前的版本依然为:0.1.0,且通过Nuget引用的是该版本且日期为:2019/5/17,因此我不知Nuget引用是最后的提交版本,还是最早提交的版本,同时的MvcCorePager分页插件实现与自定义的JavaScript代码紧密耦合,由于上述原因到目前为止它不是1个好的选择。作为分页操作的另一种实现,其源代码还是具有一定的学习价值的。

    MvcCorePager分页控件源代码,如果使用最新版本的VisualStudio打开并运行,会有许多的异常产生,从而造成该程序不能正常被执行,本人对该源代码进行了以下重构定义,从而保证该程序能够正常执行。

    1、通过Nuget把Newtonsoft.Json、Microsoft.Extensions.FileProviders.Embedded引用更新到最新的版本。

    2、在Startup.Demo.ConfigureServices方法中定义语句:

                //由于.Net(Core)3框架及其以后的版本不在支持使用app.UserMvc()内置管道中件间定义路由映射模型;

            //如果需要.Net(Core)3框架及其以后的版本能够使用app.UserMvc()内置管道中件间定义路由映射模型,则必须配置定义下面1行的语句,否则就会出现异常:

            //“System.InvalidOperationException:Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use 'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices(...).

            services.AddMvc(options => { options.EnableEndpointRouting = false; });

3Src.csproj重构:

原Src.csproj定义

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

        <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />

        <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

        <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.8" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup>

      <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />

</ItemGroup>

当前程序执行到Webdiyer.AspNetCore.PostConfigure方法中的var filesProvider = new ManifestEmbeddedFileProvider(GetType().Assembly, "wwwroot");语句时,会产生异常:“System.InvalidOperationException:Could not load the embedded file manifest 'Microsoft.Extensions.FileProviders.Embedded.Manifest.xml' for assembly 'Webdiyer.AspNetCore.MvcCorePager'.

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

        <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />

        <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup>

      <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />

      <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.8" />
</ItemGroup>

注意:必须执行“生成”按钮对“Src.csproj”执行“生成”操作直到“依赖项”中的所有“!”消失,否则在程序执行进依然会出现上述异常信息。

4、MvcCorePager插件内嵌是Ajax分页功能结合自定义的JavaScript,该JavaScript绝对是一个小众的产品,所以我对MvcCorePager插件的健壮性有着严重的担忧。

5、由于.Net(Core)x框架对比于.NetFramework框架来说极度的不稳定,和快速的被迭代,MvcCorePager插件为了适应这种变化通过对Src.csproj不断的重构,以对不同版本.Net(Core)x框架进行支持,但是我以为更好的解决方案是构建不同的版本,这样使用Nugut可以明确的引用这些第3方分页插件,下面要讲解到的PagedList.Mvc.Core分页插件就是这样做的。

对以上功能更为具体实现和注释见:MvcCorePager-master(22-08-27重构版)

3 X.PagedList.Mvc.Core分页插件

    X.PagedList.Mvc.Core分页插件中Ajax分页功能是结合jquery.unobtrusive-ajax.js中的方法实现的,jquery.unobtrusive-ajax.js,被大量的开发者高频率的使用,所以我对X.PagedList.Mvc.Core分页插件的健壮性就没有了担忧,同时由于通过版本的重构,Nuget可以根据.Net(Core)x框架明确的引用不同版本的X.PagedList.Mvc.Core分页插件,所以它是我目前能够找到的最好用于.Net(Core)x框架Web程序的分页控件。

    但是X.PagedList.Mvc.Core分页插件中Ajax分页功能基于jquery.unobtrusive-ajax.js,所以其Ajax局部刷新实现也必须基于其助记HMTL标签属性:

AjaxOptions(Ajax.BeginForm)

HTML attribute(助记HMTL标签属性)

Confirm

data-ajax-confirm

HttpMethod

data-ajax-method

InsertionMode

data-ajax-mode

LoadingElementDuration

data-ajax-loading-duration

LoadingElementId

data-ajax-loading

OnBegin

data-ajax-begin

OnComplete

data-ajax-complete

OnFailure

data-ajax-failure

OnSuccess

data-ajax-success

UpdateTargetId

data-ajax-update

Url

 data-ajax-url

    这种实现方式虽然入门容易,但是实现比较复杂的Ajax局部刷新,在与Jquery DataTables插件来说功能上就有些力有不殆了,需要开发者自定义JavaScript/Jquery来实现这些功能,这些与我们这些对JavaScript/Jquery做到基本能用的开发者而言,有悖我们的初衷,所以开发者的选择,要根据自己的实际情况,我的建议是在Jquery DataTables插件上多下功功夫。

1 X_PagedListModel

/// <summary>

    /// 【X_PagedList分页列表--类】

    /// <remarks>

    /// 摘要:

    ///     该类及其属性成员实例,为X.PagedList.Mvc.Core插件渲染显示提供基本且必须的数据支撑。

    /// </remarks>

    public class X_PagedListModel

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法为该类中的属性成员赋值实例化初始值。

        /// </remarks>

        /// </summary

        public X_PagedListModel()

        {

            //设置Jquery DataTable插件每页最多的行数(默认值):10,PageSize>=1。 

            PageSize = 10;

            PageNumber = 1;

        }

        #endregion

        #region 属性--X.PagedList.Mvc.Core插件

        /// <summary>

        /// 【页面大小】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定的X.PagedList.Mvc.Core插件每页最多的行数值:(默认值)10,PageSize>=1。 

        /// </remarks>

        /// </summary>

        public int PageSize { get; set; }

        /// <summary>

        /// 【索引】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定的X.PagedList.Mvc.Core插件指定页面相对应的索引值:(默认值)1,PageNumber>=1。 

        /// </remarks>

        /// </summary>

        public int PageNumber { get; set; }

        /// <summary>

        /// 【学生分页列表】

        /// <remarks>

        /// 摘要:

        ///     获取/设置把所有的学生实例,存储到X.PagedList.Mvc.Core插件的分页列表实例中。 

        /// </remarks>

        /// </summary>

        public IPagedList<Student> StudentIPagedList { get; set; }

        #endregion

        #region 属性--学生实体

        /// <summary>

        /// 【姓名】

        /// <remarks>

        /// 摘要:

        ///     获取/设置查询模型类1个指定实例的学生姓名。

        /// </remarks>

        /// </summary>

        [Display(Name = "姓名")]

        public string? StudnetName { get; set; }//支持空字符串查询操作,效果=“重置”。

        #endregion

    }

2 X_PagedListController

public class X_PagedListController : Controller

    {

        private readonly EFCoreContext _context;

        public X_PagedListController(EFCoreContext context)

        {

            _context = context;

        }

        public IActionResult Index(int? pageSize, int? pageNumber,  string studentName, X_PagedListModel x_PagedListModel)

        {

            // 设置分页列表模型实例。

            x_PagedListModel.PageSize = (pageSize == null || pageSize <= 0) ? x_PagedListModel.PageSize : Convert.ToInt32(pageSize);

            x_PagedListModel.PageNumber = (pageNumber == null || pageNumber <= 0) ? x_PagedListModel.PageNumber : Convert.ToInt32(pageNumber);

            x_PagedListModel.StudnetName = string.IsNullOrEmpty(studentName) ? x_PagedListModel.StudnetName : studentName;

            var customerData = (from studentsQuery in _context.Student select studentsQuery);

            //根据指定查询字符串,对所有实例进行查询操作。

            if (!string.IsNullOrEmpty(x_PagedListModel.StudnetName))

            {

                customerData = customerData.Where(m => m.StudnetName.Contains(x_PagedListModel.StudnetName));

            }

            customerData = customerData.OrderByDescending(s => s.Id);

            if (customerData.Count() % x_PagedListModel.PageSize == 0 && x_PagedListModel.PageNumber != 1)

                x_PagedListModel.PageNumber = x_PagedListModel.PageNumber - 1;

            if (customerData.Count() <= x_PagedListModel.PageSize || x_PagedListModel.PageNumber <= 1)

                x_PagedListModel.PageNumber = 1;

            x_PagedListModel.StudentIPagedList = customerData.ToPagedList(x_PagedListModel.PageNumber, x_PagedListModel.PageSize);

            return View(x_PagedListModel);

        }

        public IActionResult RenderPartial(int? pageSize, int? pageNumber, string studentName, X_PagedListModel x_PagedListModel)

        {

            // 设置分页列表模型实例。

            x_PagedListModel.PageSize = (pageSize == null || pageSize <= 0) ? x_PagedListModel.PageSize : Convert.ToInt32(pageSize);

            x_PagedListModel.PageNumber = (pageNumber == null || pageNumber <= 0) ? x_PagedListModel.PageNumber : Convert.ToInt32(pageNumber);

            x_PagedListModel.StudnetName = string.IsNullOrEmpty(studentName) ? x_PagedListModel.StudnetName : studentName;

            var customerData = (from studentsQuery in _context.Student select studentsQuery);

            //根据指定查询字符串,对所有实例进行查询操作。

            if (!string.IsNullOrEmpty(x_PagedListModel.StudnetName))

            {

                customerData = customerData.Where(m => m.StudnetName.Contains(x_PagedListModel.StudnetName));

            }

            customerData = customerData.OrderByDescending(s => s.Id);

            if (customerData.Count() % x_PagedListModel.PageSize == 0 && x_PagedListModel.PageNumber != 1)

                x_PagedListModel.PageNumber = x_PagedListModel.PageNumber - 1;

            if (customerData.Count() <= x_PagedListModel.PageSize || x_PagedListModel.PageNumber <= 1)

                x_PagedListModel.PageNumber = 1;

            x_PagedListModel.StudentIPagedList = customerData.ToPagedList(x_PagedListModel.PageNumber, x_PagedListModel.PageSize);

            return PartialView("_StudentList", x_PagedListModel);

        }

        public IActionResult AddPopup()

        {

            return View();

        }

        [HttpPost]

        public IActionResult AddPopup(Student model)

        {

            _context.Student.Add(model);//添加单个学生信息到数据库的指定表中

            _context.SaveChanges();

            ViewBag.RefreshPage = true;

            return View();

        }

        public IActionResult EditPopup(int studentId)

        {

            Student _model = _context.Student.SingleOrDefault(s => s.Id == studentId);

            return View(_model);

        }

        [HttpPost]

        public IActionResult EditPopup(Student model, int studentId)

        {

            if (model.Id == 0 && studentId != 0)

                model.Id = studentId;

            _context.Student.Update(model);//对数据库指定表1指定行中的学生信息进行更新操作

            _context.SaveChanges();

            ViewBag.RefreshPage = true;

            return View();

        }

        [HttpPost]

        public IActionResult DeleteJqueryDataTable(int pageNumber, int pageSize, int studentId, string studentName)

        {

            try

            {

                int result = 0;

                Student _model = _context.Student.SingleOrDefault(s => s.Id == studentId);

                //1、单独删除方法

                _context.Student.Remove(_model);//删除单个学生信息。

                //_context.Remove(_model);//直接在context上Remove()方法传入model,它会通过指定实体的实例,判断泛型实体的类型(Student)。

                result = _context.SaveChanges();

                X_PagedListModel _x_PagedListModel = new X_PagedListModel();

                _x_PagedListModel.StudnetName = studentName;

                return RenderPartial(pageSize, pageNumber, studentName, _x_PagedListModel);

            }

            catch (Exception)

            {

                throw;

            }

        }

        [HttpPost]

        public IActionResult DeleteIdArray(int pageNumber, int pageSize, string studentName, string studentIdArray)

        {

            try

            {

                if (!string.IsNullOrEmpty(studentIdArray))

                {

                    List<string> _idListString = studentIdArray.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();

                    List<int> _idArrayInt = _idListString.Where(pt => int.TryParse(pt, out var _)).Select(int.Parse).ToList();

                    List<Student> _studentList = new List<Student>();

                    foreach (var id in _idArrayInt)

                    {

                        Student _model = _context.Student.SingleOrDefault(s => s.Id == id);

                        _studentList.Add(_model);

                    }

                    foreach (var item in _studentList)

                    {

                        //1、单独删除方法

                        _context.Student.Remove(item);//删除单个学生信息。

                                                      //_context.Remove(_model);//直接在context上Remove()方法传入model,它会通过指定实体的实例,判断泛型实体的类型(Student)。

                        _context.SaveChanges();

                    }

                    int result = 0;

                    result = studentIdArray.Length;

                }

                X_PagedListModel _x_PagedListModel = new X_PagedListModel();

                _x_PagedListModel.StudnetName = studentName;

                return RenderPartial(pageSize, pageNumber, studentName, _x_PagedListModel);

            }

            catch (Exception)

            {

                throw;

            }

        }

    }

3 Index.cshtml

@model JsonTable.Models.X_PagedListModel

@{

    ViewData["Title"] = "学生信息";

}

@section styles

{

    <link rel="stylesheet" type="text/css" href="~/css/PagedList.css" />

}

<div id="nameListContainer" class="col-md-12">

    @await Html.PartialAsync("_StudentList", Model)

    @*

    注意:最好不要使用“@Html.Partial”,否则会出现“MVC1000”警告,原因是:使用 IHtmlHelper.Partial 或 IHtmlHelper.RenderPartial 扩展方法呈现分部将导致阻止调用。 由于线程池不足,因此这可能会导致性能降低和应用程序死锁问题(https://docs.microsoft.com/zh-cn/aspnet/core/diagnostics/mvc1000?view=aspnetcore-6.0)。

    @Html.Partial("_StudentList", Model)

    也可以直接使用“<partial/>”标签,从而避免上述的选择困难,“<partial/>”标签,是由HTML5新定义的,即HTML4及其以前的版本无该标签,只能使用  @await Html.PartialAsync/@Html.Partial实现局部渲染显示。

    <partial name="_StudentList" model="Model"/>

    *@

</div>

@section Scripts {

    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

    <script type="text/javascript" src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>

    <script type="text/javascript">

        $(document).ready(function () {

            //复选框控件联动全选操作。

            CheckAllOpiton();

        });

        function CompletedLoaded() {

            //在查询操作完成后,把复选框控件联动全选操作,加载到X.PagedList.Mvc.Core插件中;否则在查询操作完成后,复选框控件联动全选操作将不起作用。

            CheckAllOpiton();

        };

        //复选框控件联动全选操作

        function CheckAllOpiton() {

            //全选

            $("#checkAll").click(function () {

                $("[name=checkItem]:checkbox").prop("checked", this.checked);

                var idArray = "";

                if (this.checked) {

                    $("[name=checkItem]:checkbox").each(function (index) {

                        idArray = idArray + $(this).val() + ",";

                    });

                }

                else {

                    idArray = "";

                }

                GetIdArray(idArray);

            });

            //复选框组的联动效果

            $("[name=checkItem]:checkbox").click(function () {

                var idArray = "";

                var flag = true;

                $("[name=checkItem]:checkbox").each(function (index) {

                    if (!this.checked) {

                        flag = false;

                    }

                    else {

                        idArray = idArray + $(this).val() + ",";

                    }

                });

                GetIdArray(idArray);

                $("#checkAll").prop("checked", flag);

            });

        }

        function GetIdArray(idArray) {

            idArray = idArray.slice(0, -1);

            var _url = "";

            _url = $("#deleteStudentList").attr('href');

            if (idArray != "") {

                if (_url.indexOf("&studentIdArray") > -1) {

                    var _length = _url.indexOf("&studentIdArray");

                    _url = _url.slice(0, _length);

                }

                _url = _url + "&studentIdArray=" + idArray;

            }

            else {

                if (_url.indexOf("&studentIdArray") > -1) {

                    var _length = _url.indexOf("&studentIdArray");

                    _url = _url.slice(0, _length);

                }

            }

            $("#deleteStudentList").attr('href', _url);

        };

    </script>

}

4 _StudentList.cshtml

@using JsonTable.Models

@using X.PagedList;

@using X.PagedList.Mvc.Core;

@using X.PagedList.Web.Common;

@model JsonTable.Models.X_PagedListModel

<div class="row">

    <div class="col-md-12">

        @* data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" = .net framework: @using (Ajax.BeginForm("JqueryDataTableForm", "X_PagedList", new AjaxOptions() { HttpMethod = "get",UpdateTargetId = "nameListContainer" }, new { @class = "layui-form" }))}*@

        <form asp-action="RenderPartial" asp-route-pageSize="@Model.PageSize" asp-route-pageNumber="1" class="row gx-3 gy-2 align-items-center" id="JqueryDataTableForm" data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

            <div class="col-sm-3">

                <label asp-for="StudnetName" class="visually-hidden"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="col-sm-9">

                <button type="submit" id="searchStudent" class="btn btn-primary me-3">

                    <i class="fas fa-search"></i>

                    查询

                </button>

                <a asp-action="RenderPartial" asp-route-pageSize="@Model.PageSize" asp-route-pageNumber="1" type="button" class="btn btn-secondary me-3" data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

                    <i class="fa-solid fa-rotate-right"></i>

                    重置

                </a>

                <a asp-action="DeleteIdArray" asp-route-pageNumber="@Model.PageNumber" asp-route-pageSize="@Model.PageSize" asp-route-studentName="@Model.StudnetName"

                   type="button" id="deleteStudentList" class="btn btn-danger me-3" data-ajax="true" data-ajax-method="post" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

                    <i class="far fa-trash-alt"></i>

                    批量删除

                </a>

                <a type="button" class="btn btn-success float-end" onclick="OpenWindow('@(Url.Action("AddPopup", "X_PagedList",

                        new {pageSize = @Model.PageSize,studentName = @Model.StudnetName, btnId = "btnRefreshProducts", formId = "JqueryDataTableForm" }))', 500, 500, true); return false;">

                    <i class="fas fa-plus"></i>

                    添加

                </a>

                @*“btnRefreshProducts”按钮标签必须定义在“Form”标签中或去掉对“window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();”的注释。*@

                <button type="button" id="btnRefreshProducts" class="d-none"></button>

            </div>

        </form>

    </div>

</div>

<table class="table table-bordered mt-3">

    <thead>

        <tr>

            <th style="width:5%">

                <input type="checkbox" id="checkAll" class="form-check-input checkBox25" title="checkAll">

            </th>

            <th style="width:5%">编号</th>

            <th style="width:15%">学号</th>

            <th style="width:10%">姓名</th>

            <th style="width:21%">专业</th>

            <th style="width:18%">年级</th>

            <th style="width:10%">班级</th>

            <th style="width:8%"></th>

            <th style="width:8%"></th>

        </tr>

    </thead>

    <tbody>

        @foreach (var item in Model.StudentIPagedList)

        {

            <tr>

                <th>

                    <input type="checkbox" name="checkItem" value="@item.Id" class="form-check-input checkBox25" title="checkItem">

                </th>

                <th>@item.Id</th>

                <th>@item.Code</th>

                <th>@item.StudnetName</th>

                <th>@item.Specialty</th>

                <th>@item.Grade</th>

                <th>@item.Category</th>

                <th>

                    <a type="button" class="btn btn-info" onclick="OpenWindow('@(Url.Action("EditPopup", "X_PagedList",

                        new {pageSize = @Model.PageSize, pageNumber = Model.PageNumber, studentName = @Model.StudnetName, studentId = @item.Id, btnId = "btnRefreshProducts", formId = "JqueryDataTableForm" }))', 500, 500, true); return false;">

                        编辑

                    </a>

                </th>

                <th>

                  @{

                        Dictionary<string, string> _queryString = new Dictionary<string, string>

                        {

                            { "pageNumber", Model.PageNumber.ToString() },

                            { "pageSize", Model.PageSize.ToString() },

                            { "studentId", item.Id.ToString() },

                            { "studentName", Model.StudnetName },

                        };

                   }

                    <a asp-action="DeleteJqueryDataTable" class='btn btn-danger' data-ajax="true" data-ajax-method="post" data-ajax-update="#nameListContainer" asp-all-route-data="_queryString" data-ajax-complete="CompletedLoaded">删除</a>

                </th>

            </tr>

        }

    </tbody>

</table>

<div class="text-end">

    @*注意:只能是Model(IPagedList<Student>);而不能是Model.StudentIPagedList,Model(JsonTable.Models.X_PagedListModel),否则X.PagedList.Mvc.Core分页插件中的页面索引按钮将不能被正常使用*@

    @Html.PagedListPager(Model.StudentIPagedList,

    page => Url.Action("RenderPartial", new X_PagedListModel{ PageNumber=page, PageSize = Model.PageSize, StudnetName = Model.StudnetName }),

    PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(

    new PagedListRenderOptions

    {

    LinkToFirstPageFormat = "1",//分页插件中"1"/"首页"的信息模版。

    LinkToLastPageFormat = Model.StudentIPagedList.PageCount.ToString(),//分页插件中Model.PageCount.ToString()/"尾页"的信息模版

    LinkToPreviousPageFormat = "上一页",//分页插件中"上一页"的信息模版。

    LinkToNextPageFormat = "下一页",//分页插件中"下一页"的信息模版。

    DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,//分页插件中是否一直显示"1"/"首页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第1页,则不显相应的按钮;如果不是则显示"1"/"首页",则显相应的按钮;Never:从不显示。

    DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded,//分页插件中是否一直显显示Model.PageCount.ToString()/"尾页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第后1页,则不显相应的按钮;如果不是则显示Model.PageCount.ToString()/"尾页";Never:从不显示。

    DisplayLinkToPreviousPage = PagedListDisplayMode.Never,//分页插件中是否一直显示"上一页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第1页,则不显相应的按钮;如果不是显示"上一页",则显相应的按钮;Never:从不显示。

    DisplayLinkToNextPage = PagedListDisplayMode.Never,//分页插件中是否一直显示"下一页",的枚举实例值,Always:一直显示;IfNeeded:如果当前页是最后1页,则不显相应的按钮;如果不是显示"下一页",则显相应的按钮;Never:从不显示。

    //PageCountAndCurrentLocationFormat = "{0}/{1}",//分页插件显示,“{0}/{1}”的信息模版,{0}:当前页索引值;{1}:总页数值。,

    //DisplayPageCountAndCurrentLocation = true,//分页插件中是否显示,“{0}/{1}”信息,{0}:当前页索引值;{1}:总页数值。

    Display = PagedListDisplayMode.Always,//分页插件中是否一直在页面中进行显示的枚举实例值,Always:一直显示;IfNeeded:如果需要显示,如果不需要不显示;Never:从不显示。

    MaximumPageNumbersToDisplay = 5,//分页插件最多显示页面的索引值及其相应的按钮,当前显示“5”个页面的索引值及其相应的按钮,不算:"1"/"首页"、Model.PageCount.ToString()/"尾页"、"上一页"、 "下一页"的页面的索引值试及其相应的按钮。

    DisplayLinkToIndividualPages = true,//分页插件中是否为所有页面显示索引值及其相应的按钮。

    //DelimiterBetweenPageNumbers = "|",//每一页号之间会出现的文字。如果为空或空白是指定的,没有分隔符将显示。

    UlElementClasses = new[] { "pagination" },

    //ContainerDivClasses = new[] { "pagination-container" }

    ContainerDivClasses = new String[] { "pageList" }

    },

    new AjaxOptions()

    {

    HttpMethod = "POST",

    OnComplete = "CompletedLoaded",//在页面跳转操作完成后,把复选框控件联动全选操作,加载到X.PagedList.Mvc.Core插件中;否则在页面跳转操作完成后,复选框控件联动全选操作将不起作用。

    UpdateTargetId = "nameListContainer",

    }

    )

    )

    <div>

        每页 @Model.PageSize 条记录,本页有<strong class="text-danger">@Model.StudentIPagedList.Count</strong>条记录,共有 @Model.StudentIPagedList.TotalItemCount 条记录。第<strong class="text-danger">@(Model.StudentIPagedList.TotalItemCount <= Model.PageSize ? 1 : Model.PageNumber)</strong>页,共 @Model.StudentIPagedList.PageCount 页。

    </div>

</div>

5 AddPopup.cshtml

@model JsonTable.Domain.Students.Student

@{

    ViewData["Title"] = "添加学生信息";

}

@if (ViewBag.RefreshPage == true)

{

    <script type="text/javascript">

        window.opener.document.forms['@(Context.Request.Query["formId"])'].@(Context.Request.Query["btnId"]).click();

        //window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

        //window.opener.document.getElementById("resetStudent").click();

        window.close();

        //编辑操作完成后,对父窗口的当前页进行整体刷新(浏览器需要被刷新)。

        var _url = "";

        _url = decodeURI('@(Url.Action("Index", "X_PagedList", new { pageSize = Context.Request.Query["pageSize"], studentName = Context.Request.Query["studentName"].ToString() }))', "UTF-8");

        _url = _url.replace(/&amp;/g, "&");

        window.opener.location.href = _url;

        window.location.href(window.opener.location.href);

    </script>

}

<div class="row">

    <div class="col-md-4">

        <form asp-action="AddPopup"

              asp-route-pageSize="@Context.Request.Query["pageSize"]"

              asp-route-studentName="@Context.Request.Query["studentName"]"

              asp-route-btnId="@Context.Request.Query["btnId"]"

              asp-route-formId="@Context.Request.Query["formId"]">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

       

            <div class="form-group">

                <label asp-for="Code" class="control-label"></label>

                <input asp-for="Code" class="form-control" />

                <span asp-validation-for="Code" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="StudnetName" class="control-label"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Specialty" class="control-label"></label>

                <input asp-for="Specialty" class="form-control" />

                <span asp-validation-for="Specialty" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Grade" class="control-label"></label>

                <input asp-for="Grade" class="form-control" />

                <span asp-validation-for="Grade" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Category" class="control-label"></label>

                <input asp-for="Category" class="form-control" />

                <span asp-validation-for="Category" class="text-danger"></span>

            </div>

            <div class="form-group">

                <input type="submit" value="Create" class="btn btn-primary" />

            </div>

        </form>

    </div>

</div>

6 EditPopup.cshtml

@model JsonTable.Domain.Students.Student

@{

    ViewData["Title"] = "编辑学生信息";

}

@if (ViewBag.RefreshPage == true)

{

    <script type="text/javascript">

        window.opener.document.forms['@(Context.Request.Query["formId"])'].@(Context.Request.Query["btnId"]).click();

        //window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

        //window.opener.document.getElementById("resetStudent").click();

        window.close();

        //编辑操作完成后,对父窗口的当前页进行整体刷新(浏览器需要被刷新)。

        var _url = "";

        _url = decodeURI('@(Url.Action("Index", "X_PagedList", new { pageSize = Context.Request.Query["pageSize"], pageNumber = Context.Request.Query["pageNumber"], studentName = Context.Request.Query["studentName"].ToString() }))', "UTF-8");

        _url = _url.replace(/&amp;/g, "&");

        window.opener.location.href = _url;

        window.location.href(window.opener.location.href);

    </script>

}

<div class="row">

    <div class="col-md-12">

        <form asp-action="EditPopup"

              asp-route-pageSize="@Context.Request.Query["pageSize"]"

              asp-route-pageNumber="@Context.Request.Query["pageNumber"]"

              asp-route-studentName="@Context.Request.Query["studentName"]"

              asp-route-studentId="@Context.Request.Query["studentId"]"

              asp-route-btnId="@Context.Request.Query["btnId"]"

              asp-route-formId="@Context.Request.Query["formId"]">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">

                <label asp-for="Code" class="control-label"></label>

                <input asp-for="Code" class="form-control" />

                <span asp-validation-for="Code" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="StudnetName" class="control-label"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Specialty" class="control-label"></label>

                <input asp-for="Specialty" class="form-control" />

                <span asp-validation-for="Specialty" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Grade" class="control-label"></label>

                <input asp-for="Grade" class="form-control" />

                <span asp-validation-for="Grade" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Category" class="control-label"></label>

                <input asp-for="Category" class="form-control" />

                <span asp-validation-for="Category" class="text-danger"></span>

            </div>

            <div class="form-group">

                <input type="submit" value="Create" class="btn btn-primary" />

            </div>

        </form>

    </div>

</div>

    对以上功能更为具体实现和注释见:22-09-02-066_JsonTable(X.PagedList.Mvc.Core分页插件)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET Core实体框架(Entity Framework Core)是一个用于.NET Core平台的对象关系映射(ORM)框架,它提供了一种简化数据库访问和操作的方式。下面是对.NET Core实体框架的介绍: 1. 数据库上下文(DbContext):数据库上下文是.NET Core实体框架的核心组件之一,它表示与数据库的会话,并提供了对数据库的访问和操作。通过定义派生自DbContext的类,可以创建数据库上下文对象,并在其中定义实体集和数据库表之间的映射关系。 2. 实体类(Entity Class):实体类是代表数据库表的.NET类。通过定义实体类,可以将数据库表中的每一行数据映射到一个对象实例上。实体类通常包含属性来表示表中的列,并且可以定义关系属性来表示表之间的关联关系。 3. 数据迁移(Data Migration):数据迁移是.NET Core实体框架中的一个重要特性,它允许开发人员对数据库模式进行版本控制和管理。通过使用数据迁移,可以轻松地在应用程序的开发过程中对数据库模式进行更改,并将这些更改应用到目标数据库中。 4. LINQ查询(LINQ Query):.NET Core实体框架支持使用LINQ(Language Integrated Query)进行数据查询。通过使用LINQ查询,可以以面向对象的方式编写数据库查询语句,而无需直接编写SQL语句。 5. 数据库提供程序(Database Provider):.NET Core实体框架支持多种数据库提供程序,包括Microsoft SQL Server、MySQL、SQLite等。通过选择适当的数据库提供程序,可以与不同类型的数据库进行交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值