在 ASP.NET Core 中使用 WebGrid

7

我在ASP.NET Core应用程序中使用System.Web.Helpers.WebGrid控件, 在渲染网格时出现以下错误

An unhandled exception occurred while processing the request.

ArgumentNullException: Value cannot be null.
 Parameter name: httpContext

System.Web.HttpContextWrapper..ctor(HttpContext httpContext)

在第

System.Web.Helpers.WebGrid objWebGrid = new System.Web.Helpers.WebGrid(Model.MeetingsObj);

型号:

public class Meeting
    {

        public int MeetingId { get; set; }
        public string MeetingName { get; set; }
        public string Format { get; set; }
        public string Location { get; set; }
    }

    public class MeetingVM
    {
        public Meeting MeetingObj { get; set; }
        public List<Meeting> MeetingsObj { get; set; }
        public Boolean ShowGridHeader { get; set; }
    }

有人能提供上述错误的解决方案吗?

Model.MeetingsObj 的值是多少? - Luke
@Luke,Model.MeetingsObj 是一个列表。 - Saravana Kumar
请问您能否展示一下列表的定义以及其中包含的任何对象? - Luke
@Luke,已在问题中添加了模型定义。 - Saravana Kumar
@Luke,上述代码在MVC5应用程序中运行良好,但我只在ASP.NET Core中遇到了错误。 - Saravana Kumar
3个回答

21

你可以尝试使用另一个组件,我推荐MVC6网格 http://mvc6-grid.azurewebsites.net/

基本上它使用几乎相同的语法,所以对你当前的代码只会有一些小的更改,请查看下面的示例代码

@model IEnumerable<PersonModel>

@(Html
.Grid(Model)
.Build(columns =>
{
    columns.Add(model => model.Name).Titled("Name");
    columns.Add(model => model.Surname).Titled("Surname");

    columns.Add(model => model.Age).Titled("Age");
    columns.Add(model => model.Birthday).Titled("Birth date");
    columns.Add(model => model.IsWorking).Titled("Employed");

//popup part
columns.Add(model => $"<a  data-modal='' data-id=\"{model.Id}\"     href='PasswordRestUser/{model.Id}'      id=\"ss\"  asp-    action=\"PR\" asp-route-id=\"@item.Id\" class=\"btn     btn-info\" '> PR <span class='glyphicon      glyphicon-user'> </span> </a>").Encoded(false);

})
.Filterable()
.Sortable()
.Pageable()
)

<div id='myModal' class='modal fade in'>
    <div class="modal-dialog">
        <div class="modal-content">
            <div id='myModalContent'></div>
        </div>
    </div>
</div>

它还具有许多其他功能,将使得在.NET Core中更加容易。


1
它类似于ASP.NET MVC中的GRID.MVC,但是它有一些问题,比如您需要一次性提取整个模型,然后在这些行上进行过滤,如果我们获取3到5万条记录,那么它将开始出现性能问题。 - Saineshwar Bageri - MVP
1
你可以通过使用手动分页来克服这个问题,并自己完成分页部分,我相信很简单,请查看样例,http://mvc6-grid.azurewebsites.net/Grid/ManualPaging - Ali
@Ali,我喜欢你的解决方案,即使在2019年。如何在mv6网格中使用编辑和删除按钮?有没有一种简单的方法可以弹出一个窗口? - c-sharp-and-swiftui-devni
3
抱歉错过了你的评论。不幸的是,MVC网格视图无法满足你的需求,但有另外一个解决方案:http://jtable.org/ ,它能够完全满足你的需求,请查看一下。 - Ali
谢谢!我喜欢jtable和mvc-6网格。感谢您提到这些。 - Brian W.

6
你可以使用客户端Grid(jQuery DataTables Grid with ASP.NET CORE MVC),它简单、轻量级且开源。

enter image description here

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>  

    <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />  

    <link href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" rel="stylesheet" />  
    <link href="https://cdn.datatables.net/responsive/2.1.1/css/responsive.bootstrap.min.css" rel="stylesheet" />  

    <script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>  
    <script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap4.min.js "></script>  

展示网格视图的完整代码片段

@{  
    Layout = null;  
}  

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>  
<link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />  

<link href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" rel="stylesheet" />  
<link href="https://cdn.datatables.net/responsive/2.1.1/css/responsive.bootstrap.min.css" rel="stylesheet" />  

<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>  
<script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap4.min.js "></script>  

<div class="container">  
    <br />  
    <div style="width:90%; margin:0 auto;">  
        <table id="example" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">  
            <thead>  
                <tr>  
                    <th>CustomerID</th>  
                    <th>Name</th>  
                    <th>Address</th>  
                    <th>Country</th>  
                    <th>City</th>  
                    <th>Phoneno</th>  
                    <th>Edit</th>  
                    <th>Delete</th>  
                </tr>  
            </thead>  
        </table>  
    </div>  
</div>  

<script>  

        $(document).ready(function ()  
        {  
            $("#example").DataTable({  
                "processing": true, // for show progress bar  
                "serverSide": true, // for process server side  
                "filter": true, // this is for disable filter (search box)  
                "orderMulti": false, // for disable multiple column at once  
                "ajax": {  
                    "url": "/DemoGrid/LoadData",  
                    "type": "POST",  
                    "datatype": "json"  
                },  
                "columnDefs":  
                [{  
                    "targets": [0],  
                    "visible": false,  
                    "searchable": false  
                }],  
                "columns": [  
                    { "data": "CustomerID", "name": "CustomerID", "autoWidth": true },  
                    { "data": "Name", "name": "Name", "autoWidth": true },  
                    { "data": "Address", "name": "Address", "autoWidth": true },  
                    { "data": "Country", "name": "Country", "autoWidth": true },  
                    { "data": "City", "name": "City", "autoWidth": true },  
                    { "data": "Phoneno", "name": "Phoneno", "autoWidth": true },  
                    {  
                        "render": function (data, type, full, meta)  
                        { return '<a class="btn btn-info" href="/DemoGrid/Edit/' + full.CustomerID + '">Edit</a>'; }  
                    },  
                    {  
                        data: null, render: function (data, type, row)  
                        {  
                            return "<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.CustomerID + "'); >Delete</a>";  
                        }  
                    },  
                ]  

            });  
        });  


    function DeleteData(CustomerID)  
        {  
            if (confirm("Are you sure you want to delete ...?"))  
            {  
                Delete(CustomerID);  
            }  
            else  
            {  
                return false;  
            }  
        }  


        function Delete(CustomerID)  
    {  
        var url = '@Url.Content("~/")' + "DemoGrid/Delete";  

            $.post(url, { ID: CustomerID }, function (data)  
                {  
                    if (data)  
                    {  
                        oTable = $('#example').DataTable();  
                        oTable.draw();  
                    }  
                    else  
                    {  
                        alert("Something Went Wrong!");  
                    }  
                });  
    }  

</script> 

DemoGridController的完整代码片段

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Mvc;  
using ExampleGrid.Models;  
using System.Linq.Dynamic;  
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860  

namespace ExampleGrid.Controllers  
{  
    public class DemoGridController : Controller  
    {  
        private DatabaseContext _context;  

        public DemoGridController(DatabaseContext context)  
        {  
            _context = context;  
        }  
        // GET: /<controller>/  
        public IActionResult ShowGrid()  
        {  
            return View();  
        }  

        public IActionResult LoadData()  
        {  
            try  
            {  
                var draw = HttpContext.Request.Form["draw"].FirstOrDefault();  
                // Skiping number of Rows count  
                var start = Request.Form["start"].FirstOrDefault();  
                // Paging Length 10,20  
                var length = Request.Form["length"].FirstOrDefault();  
                // Sort Column Name  
                var sortColumn = Request.Form["columns[" + Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault();  
                // Sort Column Direction ( asc ,desc)  
                var sortColumnDirection = Request.Form["order[0][dir]"].FirstOrDefault();  
                // Search Value from (Search box)  
                var searchValue = Request.Form["search[value]"].FirstOrDefault();  

                //Paging Size (10,20,50,100)  
                int pageSize = length != null ? Convert.ToInt32(length) : 0;  
                int skip = start != null ? Convert.ToInt32(start) : 0;  
                int recordsTotal = 0;  

                // Getting all Customer data  
                var customerData = (from tempcustomer in _context.CustomerTB  
                                    select tempcustomer);  

                //Sorting  
                if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDirection)))  
                {  
                    customerData = customerData.OrderBy(sortColumn + " " + sortColumnDirection);  
                }  
                //Search  
                if (!string.IsNullOrEmpty(searchValue))  
                {  
                    customerData = customerData.Where(m => m.Name == searchValue);  
                }  

                //total number of rows count   
                recordsTotal = customerData.Count();  
                //Paging   
                var data = customerData.Skip(skip).Take(pageSize).ToList();  
                //Returning Json Data  
                return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data });  

            }  
            catch (Exception)  
            {  
                throw;  
            }  

        }  
    }  
}  

详细文章链接


你有一个 .NET Core 2.0 的示例吗? - Oracular Man
@OracularMan,同样适用于ASP.NET CORE 2.0,没有问题。 - Saineshwar Bageri - MVP
严格按照以下方式操作。确保@{ Layout = null; },出现以下错误[错误] TypeError: $('#dialog').dialog不是一个函数。(在'$('#dialog').dialog({ autoOpen: false, resizable: false, modal: true, width: 360 })'中,'$('#dialog').dialog'未定义) 全局代码(定义:69)还有...TypeError:未定义的函数(接近'... $('#grid').grid ...') - Oracular Man
@OracularMan,你的应用程序中是否使用了jQuery对话框?它缺少脚本引用。 - Saineshwar Bageri - MVP
1
现在使用您精彩的教程 http://www.c-sharpcorner.com/article/using-jquery-datatables-grid-with-asp-net-core-mvc/。已添加 System.Linq.Dynamic.Core; 并且 Orderby 也可以工作。正在使用 .NET Core 2.0 VS 2017 进行开发。谢谢。 - Oracular Man

0

我使用ASP.NET Core开源了WebGrid,并将其打包发布到NuGet,包名为AndreyKurdiumov.AspNetCore.Helpers - 版本号为0.2.0。

该软件包旨在成为WebGrid的就地替代品。但是,我还没有完全实现这一目标。

需要进行以下更改:

将以下行添加到 _ViewImports.cshtml 文件中:
@using AndreyKurdiumov.AspNetCore.Helpers
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor

在 WebGrid 构造的位置添加构造函数参数 HttpContextAccessor
 var grid = new WebGrid(HttpContextAccessor, source: this.Model.Tables,
         defaultSort: "TableName",
         rowsPerPage: 30);

这是尽可能简单的迁移现有代码库,我设法实现。

源代码 https://github.com/kant2002/AspNetCore.Helpers


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接