ASP.NET Core 3.1中JQuery Ajax请求[FromQuery]绑定复杂对象属性为null问题
问题根因
ASP.NET Core 3.1 相较于旧版本有两处核心变更导致绑定失败:
- 默认采用
System.Text.Json作为序列化组件,替换了之前的 Newtonsoft.Json,查询字符串模型绑定默认区分大小写。你实际请求的参数为小写驼峰格式Pager[pageIndex],而后端类属性为大写帕斯卡格式PageIndex,大小写不匹配导致属性无法绑定。 - jQuery AJAX 序列化嵌套对象时,默认会将属性名转为小写驼峰,且空数组(你示例中的
Filter: [])会被自动忽略不参与序列化,进一步导致复杂类型的子属性绑定失败。
解决方案
方案1(推荐,改动最小):适配3.1的序列化规则,恢复旧版绑定行为
先安装NuGet包Microsoft.AspNetCore.Mvc.NewtonsoftJson,再修改Startup.cs的ConfigureServices方法:
services.AddControllers() .AddNewtonsoftJson() // 换回Newtonsoft.Json序列化组件,兼容旧版绑定逻辑 .AddMvcOptions(options => { // 配置查询字符串绑定不区分大小写 var qsFactory = options.ValueProviderFactories.OfType<QueryStringValueProviderFactory>().First(); qsFactory.ValueProvider = (context) => new QueryStringValueProvider( BindingSource.Query, context.HttpContext.Request.Query, CultureInfo.InvariantCulture, caseInsensitive: true ); });
方案2:调整前端参数序列化规则
如果不想修改后端配置,可以修改前端AJAX代码,强制序列化时保留大写属性名:
var self = this; const data = { Pager: self.Pager, Filter: [] }; $.ajax({ url: self.GetItemsUrl, type: "GET", dataType: "json", busy: self.Loading, // 手动拼参数保证大小写匹配 data: { "Pager.PageIndex": self.Pager.PageIndex, "Pager.PageSize": self.Pager.PageSize, "Pager.TotalPages": self.Pager.TotalPages, "Pager.ShownRecordsCount": self.Pager.ShownRecordsCount, "Pager.TotalRecords": self.Pager.TotalRecords, "Pager.HasNextPage": self.Pager.HasNextPage, "Pager.HasPrevPage": self.Pager.HasPrevPage } }).done(function (result) { if (result.isSuccess) { self.Pager = result.data.pager; self.Items = result.data.items; } else { alert(result.data.errors[0]); } });
方案3:改用POST请求
如果没有强制使用GET的需求,直接将接口改为POST,参数从[FromQuery]改为[FromBody],可完全规避查询字符串的绑定规则问题:
后端修改:
[HttpPost] public async Task<IActionResult> GetProductsList([FromBody] PagedFilter<List<ShopFilterItem>> pagedFilter) { // 原有业务逻辑保持不变 }
前端修改:
var self = this; const data = { Pager: self.Pager, Filter: [] }; $.ajax({ url: self.GetItemsUrl, type: "POST", dataType: "json", contentType: "application/json", busy: self.Loading, data: JSON.stringify(data) }).done(function (result) { if (result.isSuccess) { self.Pager = result.data.pager; self.Items = result.data.items; } else { alert(result.data.errors[0]); } });
验证方法
你可以先直接在浏览器地址栏手动输入https://localhost:44365/ShopAPI/GetProductsList?Pager.PageIndex=0&Pager.PageSize=10访问接口,如果参数可以正常绑定,即可确认是参数大小写匹配问题,任选上述方案修复即可。
内容的提问来源于stack exchange,提问作者Nemo
相关产品推荐
相关产品推荐

