迁移至.NET Core 6后POST接口Body参数接收为null问题
.NET Core 6 迁移后POST参数接收为null修复方案
参数始终为null是两个配置/写法问题导致,和路由无关:
- .NET Core 6 对复杂类型的默认绑定规则和旧版.NET不同,不会自动从请求Body读取JSON内容反序列化,必须显式指定绑定来源
- Greasemonkey脚本中手动拼接JSON的写法生成的是非法JSON格式,序列化器无法正常解析
修复步骤
1. 修正控制器动作方法配置
首先给接口显式标记请求方法为POST,同时给复杂类型参数添加[FromBody]特性,指定从请求Body绑定数据:
[Route("api/Parsing/")] [ApiController] // 推荐添加,框架会自动做模型验证、绑定源推断,减少配置错误 public class ParsingAPIController : Controller { [HttpPost] // 显式标记只接受POST请求 [Route("Any")] public List<ParseResult> ParseAny([FromBody] ParseData parseData) { // 业务逻辑代码 } }
注:给控制器类加
[ApiController]特性后,框架会自动对复杂类型参数默认应用[FromBody]绑定,后续写接口不用重复加特性,是.NET Core API项目的标准配置。你之前尝试的直接接两个string类型参数的写法不可行:简单类型默认从查询参数/表单取值,不会读取Body中的JSON内容,且JSON序列化器无法直接把对象结构的请求体反序列化为两个单独的字符串参数。
2. 修正前端脚本的请求体构造逻辑
绝对不要手动拼接JSON字符串,这种写法遇到内容包含单引号、双引号、转义字符时会直接破坏JSON结构,这也是Postman调试正常、脚本请求失败的核心差异——Postman会自动生成合法格式的JSON。
把脚本里的请求构造改成统一序列化JS对象的写法,同时去掉不必要的eval调用:
function sendHome() { const intelData = window.PA_intel; console.log(intelData); // 先构造标准JS对象,再统一序列化 const payload = { Data: JSON.stringify(intelData), Type: 'Intel' }; GM.xmlHttpRequest({ method: "POST", url: "https://localhost:7223/api/Parsing/Any", data: JSON.stringify(payload), headers: { "Content-Type": "application/json" }, onload: function (response) { console.log(response); toastr["success"]("Intel sent home!", "Phoenix"); }, onerror: function (response) { console.log("error: ", response) }, }); }
3. 检查基础服务配置
确认Program.cs中已经正确添加控制器服务和路由映射配置,新手不要用精简的AddMvcCore,直接用AddControllers即可,避免缺少JSON序列化等必要组件:
var builder = WebApplication.CreateBuilder(args); // 注册控制器相关服务,包含JSON序列化、模型绑定等核心能力 builder.Services.AddControllers(); var app = builder.Build(); // 按顺序配置中间件,路由、CORS、授权、端点映射的顺序不要随意调整 app.UseHttpsRedirection(); app.UseRouting(); app.UseCors(); // 如有跨域配置需放在UseRouting之后、UseAuthorization之前 app.UseAuthorization(); // 映射控制器路由 app.MapControllers(); app.Run();
改完以上配置后,框架会自动读取请求Body的合法JSON内容,反序列化为ParseData类型对象,不会再出现参数为null的问题。如果需要排查绑定失败的具体原因,可以临时开启请求体日志,查看实际收到的请求内容格式是否合法。
内容的提问来源于stack exchange,提问作者Tom Parsonage
相关产品推荐
相关产品推荐

