如何在ASP.NET的PageModel中处理Fetch POST请求?
问题描述
我有一个Index.cshtml.cs文件,其中的PageModel代码如下:
namespace DemoApp.Pages { public class IndexModel : PageModel { public void OnPost() {} public void OnGet() {} public IActionResult OnPost([FromBody] JObject requestData) { System.Diagnostics.Debug.WriteLine("Request data = " + requestData); return Content("Registration successful"); } } }
同时,我想要处理如下所示的Fetch POST请求:
fetch("/Index", { method: "POST", body: jsondata, headers: { "Content-Type": "application/json", } }) .then(response => response.text()) .then(data => { alert(data); }) .catch(error => { console.error("Error:", error); });
请问该如何实现?POST请求的URL是否需要修改,还是处理方法存在问题?
解决方案
你的代码存在两个核心问题,调整后即可正常接收JSON POST请求:
1. 重载的OnPost方法导致路由匹配失败
ASP.NET Core Razor Pages无法通过参数区分重载的处理方法。当前你有两个OnPost方法(无参数和带[FromBody]参数),框架无法确定调用哪一个,直接导致请求匹配失败。
解决方式二选一:
方式一:删除无参数的OnPost方法
保留唯一的带参数OnPost方法,原URL /Index 可正常使用:
namespace DemoApp.Pages { public class IndexModel : PageModel { public void OnGet() {} public IActionResult OnPost([FromBody] JObject requestData) { System.Diagnostics.Debug.WriteLine("Request data = " + requestData); return Content("Registration successful"); } } }
方式二:为带参数方法添加命名处理程序后缀
给带参数的OnPost添加后缀(比如Submit),修改后需调整请求URL指向该命名处理程序:
namespace DemoApp.Pages { public class IndexModel : PageModel { public void OnGet() {} public void OnPost() {} // 添加命名后缀区分处理逻辑 public IActionResult OnPostSubmit([FromBody] JObject requestData) { System.Diagnostics.Debug.WriteLine("Request data = " + requestData); return Content("Registration successful"); } } }
对应的请求URL需改为 /Index?handler=Submit。
2. 缺失防伪造令牌导致400错误
Razor Pages默认启用防伪造验证,未携带令牌的JSON POST请求会直接返回400错误。
解决步骤:
- 在
Index.cshtml页面中添加防伪造令牌:
@Html.AntiForgeryToken()
- 在Fetch请求中添加
RequestVerificationToken请求头:
// 获取页面中的防伪造令牌 const token = document.querySelector('input[name="__RequestVerificationToken"]').value; // 对应方式一的请求(URL为/Index) fetch("/Index", { method: "POST", body: JSON.stringify(jsondata), // 确保数据已序列化为JSON字符串 headers: { "Content-Type": "application/json", "RequestVerificationToken": token } }) .then(response => response.text()) .then(data => { alert(data); }) .catch(error => { console.error("Error:", error); }); // 对应方式二的请求(URL带handler参数) // fetch("/Index?handler=Submit", { ... })
额外注意事项
- 必须确保请求体是序列化后的JSON字符串,使用
JSON.stringify()处理你的jsondata对象,否则会导致格式错误。 - 生产环境不建议禁用防伪造验证,若特殊场景需要,可在PageModel上添加
[IgnoreAntiforgeryToken]特性,但会带来安全风险。
内容的提问来源于stack exchange,提问作者minato.uchiha
相关产品推荐
相关产品推荐

