.NET 8 ASP.NET Core MVC中jQuery Ajax Post传JSON参数为空问题
解决.NET 8 ASP.NET Core MVC中jQuery Ajax传JSON多参数绑定问题
问题根源
.NET Core MVC和旧版ASP.NET MVC的参数绑定规则存在差异:
- 旧版ASP.NET MVC支持同时从请求体接收多个复杂参数
- .NET Core MVC默认仅允许单个复杂对象通过
[FromBody]绑定到JSON请求体,若要传递多个参数,必须调整传参方式或配置绑定规则
可行解决方案
方案1:用DTO封装所有参数(推荐)
创建一个包含Person对象和其他参数的DTO类,统一接收所有请求数据:
// DTO类 public class PersonRequestDto { public Person Person { get; set; } public string OtherParam1 { get; set; } public int OtherParam2 { get; set; } } // 控制器方法 [HttpPost] public IActionResult Submit(PersonRequestDto request) { // 处理request.Person和其他参数 return Ok(); }
前端代码:
var person = { Name: "张三", Age: 25 }; var otherParam1 = "额外参数1"; var otherParam2 = 123; $.ajax({ url: "/Home/Submit", type: "POST", contentType: "application/json; charset=utf-8", data: JSON.stringify({ Person: person, OtherParam1: otherParam1, OtherParam2: otherParam2 }), success: function(result) { console.log(result); } });
方案2:混合传参(请求体+查询字符串)
将Person对象放在JSON请求体,其他参数通过URL查询字符串传递:
// 控制器方法 [HttpPost] public IActionResult Submit([FromBody] Person person, [FromQuery] string otherParam1, [FromQuery] int otherParam2) { // 处理参数 return Ok(); }
前端代码:
var person = { Name: "张三", Age: 25 }; var otherParam1 = "额外参数1"; var otherParam2 = 123; $.ajax({ url: `/Home/Submit?otherParam1=${encodeURIComponent(otherParam1)}&otherParam2=${otherParam2}`, type: "POST", contentType: "application/json; charset=utf-8", data: JSON.stringify(person), success: function(result) { console.log(result); } });
方案3:配置兼容旧版绑定规则(不推荐,可能引发兼容性问题)
若要完全复刻旧版ASP.NET MVC的多参数JSON绑定行为,可自定义参数绑定器,调整Program.cs配置:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(options => { // 插入自定义多参数FromBody绑定器 options.ModelBinderProviders.Insert(0, new MultiFromBodyModelBinderProvider()); }); // 自定义多参数FromBody绑定器实现 public class MultiFromBodyModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType) { return new MultiFromBodyModelBinder(); } return null; } } public class MultiFromBodyModelBinder : IModelBinder { public async Task BindModelAsync(ModelBindingContext bindingContext) { var reader = new StreamReader(bindingContext.HttpContext.Request.Body); var json = await reader.ReadToEndAsync(); var model = JsonSerializer.Deserialize(json, bindingContext.ModelType); bindingContext.Result = ModelBindingResult.Success(model); } } var app = builder.Build(); // 中间件配置... app.Run();
注意:此方案可能破坏.NET Core MVC的默认绑定逻辑,仅建议在迁移旧项目时临时使用。
关键说明
- 当设置
contentType: 'application/json'时,.NET Core MVC默认只会将整个请求体绑定到一个标记了[FromBody]的参数 - 直接传递
{ person: person }时,contentType默认是application/x-www-form-urlencoded,此时参数通过表单绑定规则生效,无需[FromBody]
内容的提问来源于stack exchange,提问作者Themis Tsiligkoudis
相关产品推荐
相关产品推荐

