.NET 7 ASP.NET Core MVC前端请求时Request.Body为空问题求助
问题分析与解决方案
问题根源
前端AJAX请求未指定contentType: "application/json",导致JSON字符串被默认编码为application/x-www-form-urlencoded格式,ASP.NET Core无法正确识别该格式,部分浏览器(如Chrome)会出现Request.Body为空的情况;而Firefox对请求格式的兼容处理不同,Postman则是手动指定了正确的Content-Type,所以两者能正常工作。此外,ASP.NET Core的中间件可能提前读取过请求流,导致流位置处于末尾,也会造成读取为空。
解决方案
方案1:修正AJAX请求并重置请求流位置
前端JS修改
添加contentType配置,明确告诉服务器请求体是JSON格式:
$("#save_changes").on("click", function () { var obj = getOrderJsonData(); $.ajax({ type: "POST", url: "/studentflow/save/" + String($("#current_order").prop("value")), data: JSON.stringify(obj), contentType: "application/json", // 新增此行,指定内容类型 success: function (response) { alert("Saved") } }); });
控制器修改
读取请求体前重置流位置到开头,避免因中间件提前读取导致内容为空:
[HttpPost] [Route("/studentflow/save/{id?}")] public async Task<IActionResult> SaveFlowChanges(string id) { bool parsed = int.TryParse(id, out int orderId); if (!parsed) { return BadRequest("id is undefined"); } // 重置请求体流的位置到起始点 Request.Body.Position = 0; using (var stream = new StreamReader(Request.Body)) { var jsonString = await stream.ReadToEndAsync(); Console.WriteLine(jsonString); var result = await Order.GetOrderForConduction(orderId, jsonString); if (result.IsSuccess) { var order = result.ResultObject; await order.ConductByOrder(); return Ok(); } else { return BadRequest(result.Errors?.ErrorsToString() ?? ""); } } }
方案2:使用[FromBody]自动绑定模型(推荐)
这是ASP.NET Core官方推荐的方式,框架会自动处理JSON解析,避免手动操作流的问题。
1. 定义对应的数据模型类
根据getOrderJsonData()返回的对象结构,创建匹配的模型类:
public class OrderData { // 按实际JSON结构定义属性,示例如下: public string OrderName { get; set; } public int OrderStatus { get; set; } // 其他属性... }
2. 修改控制器方法
用[FromBody]标记参数,框架会自动将JSON请求体解析为模型对象:
[HttpPost] [Route("/studentflow/save/{id?}")] public async Task<IActionResult> SaveFlowChanges(string id, [FromBody] OrderData orderData) { bool parsed = int.TryParse(id, out int orderId); if (!parsed) { return BadRequest("id is undefined"); } // 直接使用orderData对象,如需JSON字符串可序列化 var jsonString = System.Text.Json.JsonSerializer.Serialize(orderData); Console.WriteLine(jsonString); var result = await Order.GetOrderForConduction(orderId, jsonString); if (result.IsSuccess) { var order = result.ResultObject; await order.ConductByOrder(); return Ok(); } else { return BadRequest(result.Errors?.ErrorsToString() ?? ""); } }
内容的提问来源于stack exchange,提问作者RNG_SMB
相关产品推荐
相关产品推荐

