Angular调用ASP.NET Core API报错:JSON值无法转换为System.String
问题触发原因
[FromBody]特性在ASP.NET Core中仅支持标记在动作方法的参数上,不支持标记在复杂类型的内部属性上。你将[FromBody]加在Request类的Token属性上时,系统会尝试将整个请求体的JSON内容直接反序列化为String类型,而你前端传递的是{"token":"test"}JSON对象,不是纯JSON字符串,因此反序列化失败,报错路径指向根节点$。- 前端请求路径和后端定义的路由不匹配:后端路由为
users/{userId:int:min(1)}/confirm-email,前端路径多了/email段,虽然当前可以拿到UserId,但存在路由匹配异常的隐患。
解决方案
提供两种常用修复方案,按需选择即可:
方案1:拆分参数绑定(无需修改前端传参结构)
将[FromBody]移动到控制器方法的Request参数上,路由中匹配的UserId会自动绑定到Request类的同名属性,无需额外配置:
后端修改代码
[HttpPost("users/{userId:int:min(1)}/confirm-email")] public async Task<IActionResult> ConfirmEmail([FromBody] Request request) { Response response = await _service.Send(request); return Ok(response); } public class Request { public Int32 UserId { get; set; } public String Token { get; set; } }
前端修改代码
修正请求路径,删除多余的/email段即可:
const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); var userId = 1; httpClient.post<Response>(`${this.url}/users/${userId}/confirm-email`, { token: "test" } , { headers: headers });
方案2:单独绑定Token参数(适合轻量接口)
拆分控制器方法的参数,分别标记绑定来源,适合参数少的接口场景:
后端修改代码
[HttpPost("users/{userId:int:min(1)}/confirm-email")] public async Task<IActionResult> ConfirmEmail([FromRoute] int userId, [FromBody] string token) { var request = new Request { UserId = userId, Token = token }; Response response = await _service.Send(request); return Ok(response); } public class Request { public Int32 UserId { get; set; } public String Token { get; set; } }
前端修改代码
除了修正路径外,需要将请求体改为纯字符串格式:
const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); var userId = 1; httpClient.post<Response>(`${this.url}/users/${userId}/confirm-email`, JSON.stringify("test") , { headers: headers });
内容的提问来源于stack exchange,提问作者Miguel Moura
相关产品推荐
相关产品推荐

