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

如何仅对Admin角色用户显示DataTable的编辑/删除操作列

MVC中DataTables根据用户角色隐藏操作列的解决方案

问题背景

我刚接触MVC和JavaScript,在MVC项目中使用DataTables展示数据库产品列表时遇到需求:仅Admin角色用户能看到表格最后一列的编辑、删除按钮,非Admin用户可正常加载表格但需隐藏该操作列。

之前尝试用Razor语法控制表头显示,仅隐藏了表头,操作按钮仍会显示;且在product.js中使用Razor语法无法被识别。用户角色信息存储在数据库的AspNetUsers表中。

解决方案

方法一:前端传递角色状态动态生成列

由于独立JS文件无法解析Razor语法,我们可以在Razor视图中把用户角色状态传递给全局变量,再在JS中根据该变量决定是否渲染操作列。

  1. 修改Index.cshtml,在脚本区块添加全局变量:
@section Scripts {
    <script>
        // 将用户是否为Admin的状态暴露给全局
        window.isAdmin = @User.IsInRole("Admin");
    </script>
    <script src="~/js/product.js"></script>
}
  1. 修改Index.cshtml中的表头,用Razor判断是否渲染Action列:
<thead>
    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Brand</th>
        <th>Description</th>
        @if (User.IsInRole("Admin"))
        {
            <th>Action</th>
        }
    </tr>
</thead>
  1. 修改product.js,动态生成列配置:
var dataTable;

$(document).ready(function () {
    loadDataTable();
});

function loadDataTable() {
    // 基础列配置
    let columns = [
        { data: 'productId', "width": "25%" },
        { data: 'productName', "width": "25%" },
        { data: 'productBrand', "width": "15%" },
        { data: 'productDescription', "width": "10%" }
    ];

    // 仅Admin用户添加操作列
    if (window.isAdmin) {
        columns.push({
            data: 'id',
            "render": function (data) {
                return `<div class="w-75 btn-group" role="group">
                <a href="ProductDT/Edit?id=${data}" class="btn btn-primary mx-2"><i class="bi bi-pencil-square"></i> Edit</a>
                <a onClick=Delete('ProductDT/Delete?id=${data}') class="btn btn-danger mx-2"><i class="bi bi-trash-fill"></i> Delete</a>
                </div>`;
            },
            "width": "25%"
        });
    }

    dataTable = $('#tblData').DataTable({
        ajax: { url: '/ProductDT/GetAll' },
        columns: columns
    });
}

方法二:通过DataTables配置控制列可见性

如果不想动态修改列数组,可以直接在DataTables初始化时用columnDefs配置列的可见性。

  1. 同样在Index.cshtml中传递window.isAdmin全局变量(同方法一步骤1)。

  2. 修改product.js的DataTables初始化代码:

function loadDataTable() {
    dataTable = $('#tblData').DataTable({
        ajax: { url: '/ProductDT/GetAll' },
        columns: [
            { data: 'productId', "width": "25%" },
            { data: 'productName', "width": "25%" },
            { data: 'productBrand', "width": "15%" },
            { data: 'productDescription', "width": "10%" },
            {
                data: 'id',
                "render": function (data) {
                    return `<div class="w-75 btn-group" role="group">
                    <a href="ProductDT/Edit?id=${data}" class="btn btn-primary mx-2"><i class="bi bi-pencil-square"></i> Edit</a>
                    <a onClick=Delete('ProductDT/Delete?id=${data}') class="btn btn-danger mx-2"><i class="bi bi-trash-fill"></i> Delete</a>
                    </div>`;
                },
                "width": "25%"
            }
        ],
        columnDefs: [
            // 控制第5列(索引从0开始)的可见性
            {
                targets: 4,
                visible: window.isAdmin
            }
        ]
    });
}
  1. 表头部分同样用Razor判断是否渲染Action列(同方法一步骤2)。

方法三:后端控制返回数据(更安全)

如果担心前端控制被篡改,可以在后端API中根据用户角色决定是否返回操作所需的ID,从根源上限制非Admin用户的操作权限。

  1. 修改ProductDTController的GetAll方法:
[HttpGet]
public IActionResult GetAll()
{
    bool isAdmin = User.IsInRole("Admin");
    // 根据角色决定是否返回操作ID
    var productList = _db.Products.Select(p => new 
    {
        p.productId,
        p.productName,
        p.productBrand,
        p.productDescription,
        Id = isAdmin ? p.Id : (int?)null
    }).ToList();
    return Json(new { data = productList });
}
  1. 修改product.js中的操作列渲染逻辑:
{
    data: 'id',
    "render": function (data) {
        // 非Admin用户无Id,返回空内容
        if (!data) return '';
        return `<div class="w-75 btn-group" role="group">
        <a href="ProductDT/Edit?id=${data}" class="btn btn-primary mx-2"><i class="bi bi-pencil-square"></i> Edit</a>
        <a onClick=Delete('ProductDT/Delete?id=${data}') class="btn btn-danger mx-2"><i class="bi bi-trash-fill"></i> Delete</a>
        </div>`;
    },
    "width": "25%",
    "visible": window.isAdmin
}
  1. 表头部分依旧用Razor判断是否显示(同方法一步骤2)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:20:54