JS Ajax调用WebAPI删除接口传User ID报400错误排查
问题定位
400错误的核心是三层代码的参数传递逻辑完全不匹配,另外还有拼写错误会阻断后续流程,不存在gRPC通信层面的问题,具体错误点如下:
- 前端Ajax逻辑错误:直接把jQuery对象
$Id_user拼接到URL中,实际拼接的是[object Object]字符串,根本没有拿到输入框内的用户ID值;同时后端标记了从请求体读JSON参数,但Ajax既没传请求体,也没指定JSON内容类型,后端无法解析入参。 - WebAPI参数绑定冲突:路由模板定义了
{Id_user}路径占位符,却给参数加了[FromBody]特性要求从请求体读取,ASP.NET Core无法同时从两个位置绑定同一个参数,直接触发模型验证失败。 - gRPC代码拼写错误:查询到的用户对象变量名是
data,非空判断时误写为date,就算参数正常传递,代码也会因变量不存在编译失败。
修正代码
1. gRPC服务层修正
public override async Task<Empty> Delete(UserFilter requestData, ServerCallContext context) { // 修正变量名拼写错误,保持前后一致 var data = await _context.Users_5.FindAsync(requestData.UserID); if(data == null) { // gRPC服务推荐抛出RpcException而非普通Exception,方便客户端识别错误类型 throw new RpcException(new Status(StatusCode.NotFound, "User Not Found")); } _context.Users_5.Remove(data); await _context.SaveChangesAsync(); return new Empty(); }
2. WebAPI接口层修正
两种实现方案二选一即可,优先选路径传参的写法,符合RESTful接口规范:
方案A:路径传参(推荐)
// 路由占位符名和参数名对齐,去掉[FromBody]特性,从路径读取ID [HttpDelete("{userId}")] public async Task<ActionResult<Empty>> DeleteUser(int userId) { _logger.Log(LogLevel.Information, "Request Received for AuthController::Delete"); // 组装gRPC调用需要的请求对象 var grpcRequest = new UserFilter { UserID = userId }; var results = await _userClient.DeleteAsync(grpcRequest); _logger.Log(LogLevel.Information, "Sending Response from AuthController::Delete"); return Ok(results); }
方案B:请求体传参
如果要保留从请求体读参的逻辑,就删除路由模板里的ID占位符,避免绑定冲突:
[HttpDelete] public async Task<ActionResult<Empty>> DeleteUser([FromBody] UserFilter request) { _logger.Log(LogLevel.Information, "Request Received for AuthController::Delete"); if(request == null || request.UserID <= 0) { return BadRequest("Invalid user ID"); } var results = await _userClient.DeleteAsync(request); _logger.Log(LogLevel.Information, "Sending Response from AuthController::Delete"); return Ok(results); }
3. 前端Ajax修正
对应上面选的接口方案调整,以下为对应方案A(路径传参)的代码:
const $users_A = $('#users_A'); const $userIdInput = $('#Id_user'); // 变量名和DOM元素做区分,避免混淆 // 用on替代已废弃的delegate写法 $users_A.on('click', '.remove', function () { const $li = $(this).closest('li'); // 读取输入框的实际值,不要直接拼接jQuery对象 const userId = $userIdInput.val().trim(); if(!userId) { alert('请输入要删除的用户ID'); return; } $.ajax({ url: uri_7 + userId, // 拼接真实的用户ID type: 'DELETE', success: function() { $li.fadeOut(300, function () { $(this).remove(); }); }, error: function (xhr, textStatus, errorThrown) { console.log('XHR:' + JSON.stringify(xhr) + '\nTextStatus:' + textStatus + '\nErrorThrown:' + errorThrown); } }); });
如果选方案B(请求体传参),Ajax部分需要调整为:
$.ajax({ url: uri_7, type: 'DELETE', contentType: 'application/json', // 声明请求体为JSON格式 data: JSON.stringify({ UserID: userId }), // 序列化JSON参数放到请求体 // 成功、失败回调逻辑和上面一致 })
内容的提问来源于stack exchange,提问作者José Leal
相关产品推荐
相关产品推荐

