如何将JSON文件适配C# WebAPI2 POST的ViewModel?参数为Null排查
解决WebAPI 2 POST请求参数为Null的问题
我帮你排查下这个参数为Null的问题,先梳理下你的现有代码场景:
你的JSON数据结构
{ "Data": { "DataHeader": { "MessageTrackingIdentifier": "18c64415-05cc-415e-9cf1-034bdc4dbdac", "MessageName": "USERS" }, "DataDetail": [ { "CustomerCode": "0002888802", "CustomerName": "SGG (Pty) Limited " }, { "CustomerCode": "0002034092", "CustomerName": "AAG (Pty) Limited " } ] } }
C#模型定义
public class TUserModel { public TUserDataModel Data { get; set; } } public class TUserDataModel { public TDataHeader DataHeader { get; set; } public List<TUserModelDataDetail> DataDetail { get; set; } } public class TUserModelDataDetail { public string CustomerCode { get; set; } public string CustomerName { get; set; } } public class TDataHeader { public string MessageTrackingIdentifier { get; set; } public string MessageName { get; set; } }
WebAPI动作方法
public IHttpActionResult PostUser([FromBody] TUserModel model)
AJAX及JSON读取代码
function PostUserData(viewModel) { var model = JSON.stringify(viewModel); $.ajax({ url: "http://localhost:60667/api/User", type: "POST", contentType: "application/json; charset=utf-8", dataType: "json", crossDomain: true, data: model, success: function (reply) { $('.js-call-UserApi').css("background", "green"); }, error: function (jqXHR, errorData) { alert('error: ' + JSON.stringify(jqXHR.responseText, errorData)); } }); } var oXHR = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); function reportStatus() { if (oXHR.readyState == 4) // Request completed. PostUserData(this.responseText); // All set. Now show the data. } oXHR.onreadystatechange = reportStatus; oXHR.open("GET", "UserFA.json", true); oXHR.send();
问题根源:双重序列化了JSON数据
你读取JSON文件后,this.responseText已经是JSON格式的字符串了,但你在PostUserData里又调用了JSON.stringify(viewModel),这就把原本的JSON字符串又转成了一个带引号的字符串(相当于把字符串再序列化一次)。WebAPI接收到这个内容后,无法将其解析为TUserModel类型,所以参数model就变成了Null。
修复方案
- 修改JSON读取后的处理逻辑:把
responseText解析为JavaScript对象,再传给PostUserData:
function reportStatus() { if (oXHR.readyState == 4) { // 先将JSON字符串解析为JS对象 var userData = JSON.parse(this.responseText); PostUserData(userData); } }
- 调整PostUserData函数的序列化逻辑:不需要重复序列化,直接把JS对象传给请求(jQuery会自动帮你处理序列化,或者手动序列化一次即可,但要确保传入的是JS对象而非字符串):
function PostUserData(viewModel) { $.ajax({ url: "http://localhost:60667/api/User", type: "POST", contentType: "application/json; charset=utf-8", dataType: "json", crossDomain: true, data: JSON.stringify(viewModel), // 此时viewModel是JS对象,序列化一次即可 success: function (reply) { $('.js-call-UserApi').css("background", "green"); }, error: function (jqXHR, errorData) { alert('error: ' + JSON.stringify(jqXHR.responseText, errorData)); } }); }
额外检查点
- 确保WebAPI默认的JSON格式化器没有被移除(WebAPI 2默认支持JSON解析,除非你自定义配置时删掉了相关组件)。
- 通过浏览器开发者工具的Network面板,确认请求的
Content-Type确实是application/json; charset=utf-8。 - 模型类的属性名称要和JSON的键完全匹配(你的模型和JSON结构是匹配的,这一点没问题)。
内容的提问来源于stack exchange,提问作者Neal Rogers
相关产品推荐
相关产品推荐

