Fetch API无法POST JSON数据至.NET 9控制器的问题排查
排查Fetch API调用.NET 9控制器400错误的原因
核心问题定位与解决方案
1. AntiForgeryToken 头部名称不匹配
.NET MVC默认要求的AntiForgeryToken请求头是RequestVerificationToken,而你代码中使用的是自定义的MY-XSRF-TOKEN,这会直接触发验证失败,导致请求被拦截在服务器入口,根本无法抵达控制器方法。
解决方法:
将请求头中的MY-XSRF-TOKEN替换为默认的RequestVerificationToken:
headers: { "Accept": "application/json", "Content-Type": "application/json", "RequestVerificationToken": token.value }
2. Fetch API异步逻辑处理错误
Fetch返回的是Promise对象,你当前代码直接同步判断response.ok,会在请求未完成时就执行错误逻辑,同时无法正确捕获服务器返回的错误信息。
解决方法:
改用async/await处理异步流程,并添加event.preventDefault()阻止表单默认提交行为:
Main.AddCategory = async (event) => { event.preventDefault(); const form = event.currentTarget.closest('form'); const name = form.querySelector('#Name').value.trim(); const desc = form.querySelector('#Description').value.trim(); const token = document.getElementsByName("__RequestVerificationToken")[0].value; const actionLink = event.currentTarget.dataset.actionLink; try { const response = await fetch(actionLink, { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json", "RequestVerificationToken": token }, body: JSON.stringify({ Name: name, Description: desc }) }); if (!response.ok) { const errorDetails = await response.json(); throw new Error(`保存分类失败:${errorDetails.Message || '未知错误'}`); } const result = await response.json(); console.log(result.Message); // 这里可添加成功后的UI操作(如关闭模态框) } catch (error) { console.error(error.message); } };
3. 表单输入name属性与业务逻辑不匹配
当前表单中Name输入框的name属性为First,Description输入框的name属性为Last,虽然当前通过ID取值不影响,但后续如果改用表单序列化方式提交会引发字段不匹配问题,建议统一为DTO对应的字段名:
<input id="Name" name="Name" placeholder="Name" type="text" class="validate"> <input id="Description" name="Description" placeholder="Description" type="text" class="validate">
4. 后端JsonResult写法兼容问题
.NET 9属于ASP.NET Core生态,旧版System.Web.Mvc.JsonRequestBehavior.AllowGet已不再适用,ASP.NET Core默认允许GET请求返回JSON,无需额外指定参数。
解决方法:
修改控制器返回语句:
return Json(new { Success = false, Message = "Failure creating category: " + categoryDTO.Name }); // 以及 return Json(new { Success = true, Message = $"The category, {categoryDTO.Name} was created successfully." });
5. 可选优化:DTO字段验证
若需要强制校验必填字段,可在CategoryDTO中添加数据注解:
public class CategoryDTO { [Required(ErrorMessage = "分类名称不能为空")] public string? Name { get; set; } public string? ProductId { get; set; } public string? Description { get; set; } }
内容的提问来源于stack exchange,提问作者JakeFromStateFarm
相关产品推荐
相关产品推荐

