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

ASP.NET Core控制器如何获取Antiforgery Token并嵌入Kendo Grid表单

解决方案

方法1:在控制器Action中获取防伪令牌

你可以通过ASP.NET Core内置的IAntiforgery服务直接在控制器中获取__RequestVerificationToken,步骤如下:

  1. 在控制器构造函数中注入IAntiforgery服务
  2. 在Search方法中调用GetAndStoreTokens方法获取当前请求对应的防伪令牌
  3. 修改Grid的ClientTemplate,在动态生成的表单中添加令牌隐藏域

控制器代码修改示例

public class ItemsController : Controller
{
    private readonly IAntiforgery _antiforgery;
    private readonly IItemService _Service;

    public ItemsController(IAntiforgery antiforgery, IItemService service)
    {
        _antiforgery = antiforgery;
        _Service = service;
    }

    [HttpPost]
    [Route("items/search")]
    public async Task<ActionResult> Search([DataSourceRequest] DataSourceRequest request)
    {
        // 获取当前会话的防伪令牌,同一会话下所有请求的令牌通用
        var requestToken = _antiforgery.GetAndStoreTokens(HttpContext).RequestToken;
        
        var workItems = await _Service.GetItems();
        var result = workItems.Select(x => new ItemModel()
        {
            ID = x.ID,
            Name = x.Name,
            Token = requestToken
        }).ToList().ToDataSourceResult(request);
         
        return Json(result);
    }

    [HttpPost]
    [Route("items/{id}/copy")]
    public async Task<ActionResult> Copy([FromRoute]int id)
    {
        // 此处执行业务逻辑
    }
}

Grid代码修改示例

@(Html.Kendo().Grid<ItemModel>()
    .Name("SearchItems")
    .Columns(col =>
    {
        col.Bound(p => p.ID).Title("ID").Width(75);
        col.Bound(p => p.Name);                        
        col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><input type='hidden' name='__RequestVerificationToken' value='#: Token #' /><button type='submit' class='btn btn-link'>copy</button></form>");
    })
    .AutoBind(true)
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(m=>m.Id(p=>p.WorkItemID))
        .PageSize(50)
        .ServerOperation(true)
        .Read(read => read.Action("Search", "Items"))
    )
)

方法2:更优实现(无需修改控制器代码)

因为同一会话下防伪令牌是通用的,不需要给每个列表项单独赋值,你可以直接在Razor视图中提前获取令牌,直接注入到ClientTemplate中即可:

  1. 在Razor视图顶部注入IAntiforgery服务,把令牌存为全局JS变量
  2. 直接在ClientTemplate中引用全局令牌变量

Razor视图代码示例

@inject IAntiforgery Antiforgery
@* 其他页面代码 *@

<script>
    // 页面加载时直接获取当前会话的防伪令牌
    const globalAntiForgeryToken = '@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken';
</script>

@(Html.Kendo().Grid<ItemModel>()
    .Name("SearchItems")
    .Columns(col =>
    {
        col.Bound(p => p.ID).Title("ID").Width(75);
        col.Bound(p => p.Name);                        
        col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><input type='hidden' name='__RequestVerificationToken' value='" + globalAntiForgeryToken + "' /><button type='submit' class='btn btn-link'>copy</button></form>");
    })
    .AutoBind(true)
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(m=>m.Id(p=>p.WorkItemID))
        .PageSize(50)
        .ServerOperation(true)
        .Read(read => read.Action("Search", "Items"))
    )
)

这个方法不需要修改控制器代码,也避免了给每个列表项重复赋值相同令牌的冗余操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:42:02