ASP.NET Core MVC中Ajax传值至控制器始终为空的问题排查
问题
我正尝试在ASP.NET Core MVC应用中通过Ajax实现事件添加功能:
View.cshtml代码如下:
function Add() { var eventdto = {}; eventdto.id = "F51B27EE-27F6-4C50-BD81-08DBF0494506"; eventdto.Title = $('#Title').val(); eventdto.Description = $('#Description').val(); eventdto.Start = $('#Start').val(); eventdto.End = $('#End').val(); eventdto.AllDay = $('#AllDay').val(); eventdto.Url = $('#Url').val(); eventdto.BackgroundColor = $('#BackgroundColor').val(); $.ajax({ type: "POST", url: "/Home/JsonTest", data: '{eventdto: ' + JSON.stringify(eventdto) + '}', contentType: "application/json;charset=utf-8", dataType: "json", success: function (result) { $('#schedule').modal('hide'); }, error: function (errormessage) { alert(errormessage.responseText); } }); }
Controller.cs代码如下:
[HttpPost] public JsonResult JsonTest(EventDTO eventdto) { return Json(eventdto); }
前端已成功生成eventdto对象,但控制器中接收的eventdto始终为null。我尝试了多种传参方式:
data: eventdto,data: {eventdto},data: {eventdto: eventdto},- 手动构造嵌套对象:
data: { eventdto: { "title" : "asdasd", description : "asdasd", start : "asdasd", end : "asdasd", allDay : "asdasd", url : "asdasd", backgroundColor : "asdasd" } },
同时也尝试了网上的多种解决方案(如[FromBody]、修改参数名为"data"等),但问题仍未解决,请问我哪里操作有误?
解决方案
核心问题及修复步骤
- 必须添加
[FromBody]特性
ASP.NET Core MVC默认不会从请求体中绑定复杂类型参数,必须显式标记[FromBody]才能正确解析JSON请求体:
[HttpPost] public JsonResult JsonTest([FromBody] EventDTO eventdto) { return Json(eventdto); }
- 修正Ajax的
data格式
不要手动拼接JSON字符串,直接传入序列化后的对象即可,无需额外嵌套eventdto键:
$.ajax({ type: "POST", url: "/Home/JsonTest", data: JSON.stringify(eventdto), // 直接序列化对象,不要包裹外层 contentType: "application/json;charset=utf-8", dataType: "json", success: function (result) { $('#schedule').modal('hide'); }, error: function (errormessage) { alert(errormessage.responseText); } });
确保前后端属性名匹配
C#默认使用PascalCase(大驼峰)命名,而JS中如果用camelCase(小驼峰)会导致绑定失败,可通过两种方式解决:- 开启大小写不敏感绑定:在
Program.cs中配置JSON序列化选项:builder.Services.AddControllersWithViews() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; }); - 显式指定属性映射:给
EventDTO的属性添加[JsonPropertyName]特性,匹配前端键名:using System.Text.Json.Serialization; public class EventDTO { public Guid Id { get; set; } [JsonPropertyName("Title")] // 匹配前端的Title public string Title { get; set; } [JsonPropertyName("Description")] public string Description { get; set; } // 其他属性同理配置 }
- 开启大小写不敏感绑定:在
修正数据类型错误
如果AllDay是布尔值属性,前端用$('#AllDay').val()会得到字符串(如"on"),需改为获取复选框状态:
eventdto.AllDay = $('#AllDay').is(':checked'); // 正确获取布尔值
常见误区排查
- 手动拼接JSON字符串容易出现语法错误,始终使用
JSON.stringify()序列化对象 - 若后端参数是嵌套对象(如
{ eventdto: ... }),则需要定义对应的包装类,而不是直接用EventDTO作为参数 - 检查请求头
contentType是否为application/json;charset=utf-8,否则ASP.NET Core不会按JSON解析请求体
内容的提问来源于stack exchange,提问作者kaseta
相关产品推荐
相关产品推荐

