异步jQuery Ajax向WebAPI提交数据始终为空的问题排查
问题解决方案:jQuery 3.x + Async/Await + WebAPI 2.0 数据提交问题
核心问题原因
WebAPI 2.0中,[FromBody]绑定单个string类型参数时,默认期望请求体是纯字符串内容或JSON格式的单个字符串,而jQuery的$.ajax默认会将data: {UserId: userId}编码为application/x-www-form-urlencoded格式的键值对(如UserId=123),这种格式WebAPI无法解析为单个string参数,导致后端接收到null。
可行解决方案
方案一:前端发送纯文本内容(适配后端现有string参数)
修改前端请求,指定contentType为text/plain,直接传递userId字符串而非对象:
async function RetrieveProfile(userId) { let result; try { result = await $.ajax({ url: '../../api/GetProfile', dataType: 'json', method: 'post', contentType: 'text/plain', // 关键:指定纯文本类型 data: userId // 直接传入字符串值 }); return result; } catch (e) { console.error(e); } }
方案二:后端改用DTO类接收(推荐,扩展性更强)
如果后续可能传递更多参数,定义DTO类统一接收请求数据,WebAPI可自动解析JSON格式的请求体:
后端代码修改
// 新增请求DTO类 public class ProfileRequest { public string UserId { get; set; } } [Route("api/GetProfile")] [HttpPost] public async Task<IHttpActionResult> GetProfile([FromBody] ProfileRequest request) { var retval = new Profile(); if (request?.UserId != null) { if (await dbv.IsValidUserIdAsync(request.UserId)) { retval = await profile_Data.GetProfileAsync(request.UserId); } } return Ok(retval); }
对应前端代码(发送JSON格式数据)
async function RetrieveProfile(userId) { let result; try { result = await $.ajax({ url: '../../api/GetProfile', dataType: 'json', method: 'post', contentType: 'application/json', // 指定JSON内容类型 data: JSON.stringify({ UserId: userId }) // 序列化为JSON字符串 }); return result; } catch (e) { console.error(e); } }
方案三:前端发送JSON格式的单个字符串(适配后端现有string参数)
如果不想修改后端结构,可直接序列化userId为JSON格式的单个字符串(需包含双引号):
async function RetrieveProfile(userId) { let result; try { result = await $.ajax({ url: '../../api/GetProfile', dataType: 'json', method: 'post', contentType: 'application/json', data: JSON.stringify(userId) // 序列化后为"xxx"格式 }); return result; } catch (e) { console.error(e); } }
关键注意事项
- jQuery 3.1.1的
$.ajax返回的Deferred对象兼容Promise,因此async/await的使用没有问题,无需升级jQuery版本。 - 不要移除
[FromBody]特性:WebAPI默认对POST请求的简单类型参数会从URL或表单取值,只有加[FromBody]才会从请求体解析数据。 - Postman测试验证:若测试单个string参数,需在Body中选择
raw,格式选Text直接输入用户ID,或选JSON输入带双引号的字符串(如"123")。
内容的提问来源于stack exchange,提问作者MC9000
相关产品推荐
相关产品推荐

