You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1中JQuery Ajax请求[FromQuery]绑定复杂对象属性为null问题

问题根因

ASP.NET Core 3.1 相较于旧版本有两处核心变更导致绑定失败:

  1. 默认采用 System.Text.Json 作为序列化组件,替换了之前的 Newtonsoft.Json,查询字符串模型绑定默认区分大小写。你实际请求的参数为小写驼峰格式 Pager[pageIndex],而后端类属性为大写帕斯卡格式 PageIndex,大小写不匹配导致属性无法绑定。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:27:04