ASP.NET Core Razor表单提交触发AntiforgeryValidationException异常求助
尝试通过表格中的复选框修改记录的勾选状态并保存到数据库,表单能正确加载所有记录及当前勾选状态,但当表格中包含多个<input>元素(比如同时包含隐藏的Id字段和复选框)时,提交表单会抛出防伪令牌验证异常。仅保留isChecked字段时表单正常工作,但必须传递Id字段才能在后台更新对应记录,且单个<input>时无异常。
异常信息:
Exception thrown: 'Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException' in Microsoft.AspNetCore.Antiforgery.dll
Exception thrown: 'Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException' in System.Private.CoreLib.dll
已尝试添加@Html.AntiForgeryToken()及[ValidateAntiForgeryToken]特性,但无效。
.cshtml页面代码
@if (Model.listAircraftModels != null && Model.listAircraftModels.Any()) { <form method="post"> <div class="container"> @* @Html.AntiForgeryToken() *@ <table class="table"> <thead> <tr> <td>Active</td> <td>Mfg</td> <td>Make</td> <td>Model</td> <td>Size Category</td> </tr> </thead> <tbody> @for (int i = 0; i < Model.listAircraftModels.Count(); i++) { <tr> <td> // If I comment out the hidden input everything works. More than one <input> in this or any <td> causes the error <input asp-for="listAircraftModels[i].Id" type="hidden" /> <input asp-for="listAircraftModels[i].isChecked" type="checkbox" /> </td> <td> @Model.listAircraftModels[i].mfg </td> <td> @Model.listAircraftModels[i].make </td> <td> @Model.listAircraftModels[i].model </td> <td> @Model.listAircraftModels[i].sizeCategory </td> </tr> } </tbody> </table> <input class="btn btn-dark me-2" type="submit" value="Submit" /> </div> </form> } else { <div class="container"> <p>No aircraft models found!</p> </div> }
.cshtml.cs后台代码
[Authorize()] public class OverviewModel : PageModel { private readonly IAircraftModelsRepository aircraftModelsRepository; [BindProperty] public List<AllAircraftModels> listAircraftModels { get; set; } public OverviewModel(IAircraftModelsRepository aircraftModelsRepository) { this.aircraftModelsRepository = aircraftModelsRepository; } public async Task OnGet() { listAircraftModels = (await aircraftModelsRepository.GetAsync())?.ToList(); } //[ValidateAntiForgeryToken] Tried, but this but it didn't work public async Task<IActionResult> OnPostAsync() { foreach (var aircraftModel in listAircraftModels) { await aircraftModelsRepository.UpdateAsync(aircraftModel); } return RedirectToPage("/AircraftModel/Overview"); } }
模型代码
public class AllAircraftModels { public Guid Id { get; set; } public int modelId { get; set; } public string mfg { get; set; } public string make { get; set; } public string model { get; set; } public string sizeCategory { get; set; } public bool isChecked { get; set; } }
解决方案
修复HTML错误注释:Razor视图的HTML部分不能用
//注释,这会被输出到页面成为无效文本,破坏表单结构。将<td>内的// If I comment out...改为HTML注释格式:<!-- 如果注释掉隐藏的input,一切正常。当前<td>或其他<td>中包含多个<input>就会触发错误 -->确保防伪令牌正确配置:
- 取消
@Html.AntiForgeryToken()的注释,确保表单中包含防伪令牌字段; - 恢复
OnPostAsync()上的[ValidateAntiForgeryToken]特性,确保后台验证防伪令牌。
- 取消
检查模型绑定完整性:确保
AllAircraftModels类的所有属性都允许绑定(没有[BindNever]特性),且for循环生成的input标签name属性格式正确(如listAircraftModels[0].Id)。调整表单提交大小限制(可选):如果列表条目过多,表单数据可能超过ASP.NET Core默认的请求大小限制,导致请求截断引发验证失败。可在Program.cs中添加配置:
builder.Services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = 10485760; // 10MB,按需调整 options.ValueLengthLimit = int.MaxValue; });
内容的提问来源于stack exchange,提问作者confusedUser1

