Angular前端触发POST请求时出现System.Nullable错误,未调用后端接口
问题背景
预期流程:用户点击按钮后,前端发送POST请求到/api/designer,后端AddUniqueAsync方法创建数据库条目,返回带Location头的201响应;前端获取Location中的URL后,发送GET请求到UniqueByDs接口。
实际异常:点击按钮后后端接口未执行,浏览器抛出System.Nullable相关错误。
一、后端代码问题点
1. 路由参数匹配错误
AddUniqueAsync中调用CreatedAtRoute时,路由参数拼写错误:targerProject(多了一个r),但UniqueByDs接口的参数是targetProject,这会导致路由生成失败,甚至触发模型绑定异常。UniqueByDs接口的loopID参数是string类型,但UniqueIdDto的Loop是int?类型,类型不匹配会导致路由生成失败,或模型绑定出错。
2. 模型绑定潜在问题
UniqueIdDto的属性为大写开头(如DSNumber、Project),但前端传递的是小写键名(如dsNumber、project)。虽然ASP.NET Core默认支持驼峰映射,但如果全局配置异常,会导致请求体绑定失败,后端无法接收参数,直接返回400错误,表现为接口“未触发”。
3. 异常处理不规范
AddUniqueAsync直接throw异常,未做捕获处理;且未添加模型状态校验,无法返回具体的绑定错误信息,导致问题定位困难。
二、前端代码问题点
1. 参数类型不匹配
前端传递的loop是字符串格式(如"Loop-2"),但后端UniqueIdDto的Loop是int?类型,这会直接导致请求体模型绑定失败,后端返回400错误,接口逻辑无法执行。
2. 响应处理不全面
前端postProjectAndDsNums方法仅处理了201和500状态码,未覆盖400(参数错误)等常见错误状态,导致错误信息不明确,无法快速定位问题。
三、修复建议
后端修复
修正路由参数拼写与类型
修改AddUniqueAsync中的CreatedAtRoute参数,确保与UniqueByDs接口的参数一致:// 修正拼写错误,并将int?类型的Loop转为string匹配接口参数 return CreatedAtRoute("UniqueByDs", new { uniqueDs = id.DSNumber, targetProject = id.Project, loopID = id.Loop?.ToString() }, id);或直接将
UniqueIdDto的Loop改为string?类型,匹配前端传递的字符串格式:public class UniqueIdDto { // ...其他属性 public string? Loop { get; set; } }添加模型状态校验
在AddUniqueAsync开头增加模型状态检查,返回具体绑定错误:[HttpPost] [AllowAnonymous] public async Task<IActionResult> AddUniqueAsync([FromBody] UniqueIdDto id, CancellationToken cancellationToken) { if (!ModelState.IsValid) { return BadRequest(ModelState); // 返回具体的参数错误信息 } // ...原有逻辑 }
前端修复
统一参数类型
如果后端Loop保持int?类型,前端需将字符串格式的selectedLoop转为数字:// 从"Loop-2"中提取数字2 const loopNumber = parseInt(this.selectedLoop.split('-')[1]); const userEnteredData = { "dsNumber": this.selectedDsNumber, "issue": this.selectedIssue, "task": this.selectedTask, "project": this.selectedProject, "user": this.userName, "loop": loopNumber };如果后端
Loop改为string?类型,保持原有传递逻辑即可。完善错误处理
在postProjectAndDsNums的error回调中打印完整错误信息,并处理400状态:error: (error) => { console.error('请求错误详情:', error.status, error.error); if (error.status === 400) { alert('参数格式错误,请检查输入内容'); } else if (error.status === 500) { alert('该DS编号已存在'); } else { alert('操作失败,请稍后重试'); } }
内容的提问来源于stack exchange,提问作者AoLiGei

