You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6+项目使用WebGrid遭遇IHtmlString未找到错误求助

问题原因

WebGrid和Microsoft.AspNet.WebPages这类组件是.NET Framework时代的产物,依赖仅存在于旧框架中的System.Web.dll(包含IHtmlString),而ASP.NET Core完全重构了底层架构,移除了System.Web相关依赖,因此这些旧组件无法在.NET 6环境中正常工作,必须更换兼容方案。

解决方案

方案一:原生实现分页+排序(无第三方依赖)

适合轻量需求,直接通过ASP.NET Core最小API+前端代码实现。

  1. 卸载旧NuGet包
    移除所有与Microsoft.AspNet.WebPages相关的包,避免版本冲突。

  2. 定义数据模型与分页参数
    在Program.cs中添加基础模型类:

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
    
    public class PaginationParams
    {
        public int PageIndex { get; set; } = 1;
        public int PageSize { get; set; } = 10;
        public string SortBy { get; set; } = "Id";
        public bool IsAscending { get; set; } = true;
    }
    
  3. 实现后端分页排序逻辑
    结合EF Core完成数据库查询(需先安装Microsoft.EntityFrameworkCore及对应数据库Provider,如Microsoft.EntityFrameworkCore.SqlServer):

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddDbContext<AppDbContext>(options => 
        options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
    
    var app = builder.Build();
    
    // 分页排序接口
    app.MapGet("/products", async (AppDbContext db, [AsParameters] PaginationParams param) =>
    {
        var query = db.Products.AsQueryable();
    
        // 动态排序
        query = param.IsAscending 
            ? query.OrderBy(p => EF.Property<object>(p, param.SortBy))
            : query.OrderByDescending(p => EF.Property<object>(p, param.SortBy));
    
        // 分页计算
        var totalItems = await query.CountAsync();
        var items = await query
            .Skip((param.PageIndex - 1) * param.PageSize)
            .Take(param.PageSize)
            .ToListAsync();
    
        return Results.Ok(new {
            TotalItems = totalItems,
            PageIndex = param.PageIndex,
            PageSize = param.PageSize,
            Items = items
        });
    });
    
    // 启用静态文件支持(用于前端页面)
    app.UseStaticFiles();
    app.Run();
    
  4. 前端表格实现
    在wwwroot目录下创建index.html,通过原生JS渲染分页排序表格:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Product Grid</title>
        <style>
            table { border-collapse: collapse; width: 100%; margin: 20px 0; }
            th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            th { cursor: pointer; background-color: #f5f5f5; }
            .pagination button { margin: 0 2px; padding: 4px 8px; cursor: pointer; }
            .active { background-color: #007bff; color: white; border: none; }
        </style>
    </head>
    <body>
        <table id="productTable">
            <thead>
                <tr>
                    <th data-sort="Id">ID</th>
                    <th data-sort="Name">Name</th>
                    <th data-sort="Price">Price</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
        <div class="pagination" id="pagination"></div>
    
        <script>
            let currentPage = 1;
            let currentSortBy = "Id";
            let currentIsAscending = true;
            const pageSize = 10;
    
            async function loadProducts() {
                const res = await fetch(`/products?PageIndex=${currentPage}&PageSize=${pageSize}&SortBy=${currentSortBy}&IsAscending=${currentIsAscending}`);
                const data = await res.json();
                
                // 渲染表格内容
                const tbody = document.querySelector("#productTable tbody");
                tbody.innerHTML = data.Items.map(p => `
                    <tr>
                        <td>${p.Id}</td>
                        <td>${p.Name}</td>
                        <td>$${p.Price.toFixed(2)}</td>
                    </tr>
                `).join('');
    
                // 渲染分页控件
                const pagination = document.querySelector("#pagination");
                pagination.innerHTML = '';
                const totalPages = Math.ceil(data.TotalItems / pageSize);
                
                // 上一页按钮
                if (currentPage > 1) {
                    const prevBtn = document.createElement('button');
                    prevBtn.textContent = 'Prev';
                    prevBtn.onclick = () => { currentPage--; loadProducts(); };
                    pagination.appendChild(prevBtn);
                }
    
                // 页码按钮
                for (let i = 1; i <= totalPages; i++) {
                    const btn = document.createElement('button');
                    btn.textContent = i;
                    btn.className = i === currentPage ? 'active' : '';
                    btn.onclick = () => { currentPage = i; loadProducts(); };
                    pagination.appendChild(btn);
                }
    
                // 下一页按钮
                if (currentPage < totalPages) {
                    const nextBtn = document.createElement('button');
                    nextBtn.textContent = 'Next';
                    nextBtn.onclick = () => { currentPage++; loadProducts(); };
                    pagination.appendChild(nextBtn);
                }
            }
    
            // 表头排序事件
            document.querySelectorAll('#productTable th').forEach(th => {
                th.addEventListener('click', () => {
                    const sortBy = th.dataset.sort;
                    if (sortBy === currentSortBy) {
                        currentIsAscending = !currentIsAscending;
                    } else {
                        currentSortBy = sortBy;
                        currentIsAscending = true;
                    }
                    currentPage = 1; // 排序后重置到第一页
                    loadProducts();
                });
            });
    
            // 初始加载数据
            loadProducts();
        </script>
    </body>
    </html>
    

方案二:使用前端网格组件(如DataTables.js)

适合快速实现复杂表格功能(含分页、排序、搜索),无需手动编写分页逻辑。

  1. 引入DataTables资源
    修改index.html,添加CDN链接:

    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
    
  2. 简化前端代码
    利用DataTables自动处理分页排序:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Product Grid</title>
        <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
        <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
        <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
    </head>
    <body>
        <table id="productTable" class="display" style="width:100%">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    
        <script>
            $(document).ready(async function() {
                // 可返回全部数据让DataTables处理,或配置服务器端分页(适合大数据量)
                const res = await fetch("/products?PageSize=100");
                const data = await res.json();
                
                $("#productTable").DataTable({
                    data: data.Items,
                    columns: [
                        { data: "Id" },
                        { data: "Name" },
                        { data: "Price", render: p => `$${p.toFixed(2)}` }
                    ],
                    paging: true,
                    searching: true,
                    ordering: true
                });
            });
        </script>
    </body>
    </html>
    

内容的提问来源于stack exchange,提问作者dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:45:23