如何在两个C# API之间传递无定义类的dynamic对象,解决415错误
问题原因
1. Postman调用触发415的直接原因
第一个API的processPensionInput方法参数标记了[FromBody],ASP.NET Core要求这类请求必须携带Content-Type: application/json请求头,Postman发送请求时如果没有配置该头,或者Body格式不是JSON,就会直接返回415 Unsupported Media Type。
2. 两个API间调用的错误
你当前使用GET请求把JSON串拼接在URL查询参数中调用第二个API,存在两个问题:
- 第二个API的
inputFromPensioner参数没有标记[FromQuery],默认会从请求Body读取参数,而GET请求没有Body,会触发参数绑定失败,返回415 - JSON串拼接在URL中会有长度限制,且特殊字符容易转义错误,完全不适合传复杂对象
3. 代码其他明显错误
第一个API中你在判断状态码之前就执行了return Ok(responseTalk.Result);,后续的状态码判断逻辑完全不会执行,属于不可达代码。
修复步骤
第一步:修复Postman调用配置
调用第一个API时,在Postman中:
- 请求方式选POST
- Body tab选择
raw,格式下拉选择JSON - 输入对应的JSON请求体,发送即可避免415错误
第二步:修改两个API的交互逻辑
改为用POST请求传递JSON Body,代码修改如下:
第一个API修改后代码
// 建议改为异步方法避免死锁 public async Task<IActionResult> processPensionInput([FromBody]dynamic inputFromPensionerBody) { // 生产环境建议用IHttpClientFactory注入HttpClient,不要每次using创建 using(var askPensionDisbursement = new HttpClient()) { askPensionDisbursement.BaseAddress = new Uri("http://localhost:51549/api/PensionDisbursements/"); // 构造JSON格式的请求内容 var jsonString = JsonConvert.SerializeObject(inputFromPensionerBody); var requestContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); // 异步发送POST请求 var responseTalk = await askPensionDisbursement.PostAsync("calculatefromdetails", requestContent); int code = (int)responseTalk.StatusCode; if(code == 10) { var readResult = await responseTalk.Content.ReadAsStringAsync(); return Ok("Okay"); } return Ok("Not okay"); } }
第二个API修改后代码
// 明确标记为POST接口,参数加[FromBody]从请求体读取 [HttpPost] public IActionResult calculatefromdetails([FromBody] dynamic inputFromPensioner/*,dynamic serviceCharge*/) { StatusCodeResult flag = new StatusCodeResult(21); using (var response = new HttpClient()) { // 原有业务逻辑 } return new StatusCodeResult(10); }
额外优化建议
- 尽量避免用
dynamic作为接口参数,定义强类型的DTO类做参数绑定,可以在编译期发现参数错误,避免运行时异常 - 不要使用
.Wait()或者.Result阻塞异步调用,改为async/await的异步写法,可以避免线程死锁 - 不要每次请求都新建
HttpClient实例,ASP.NET Core中建议用IHttpClientFactory注入HttpClient实例,避免端口耗尽问题
内容的提问来源于stack exchange,提问作者Harsha Gangari
相关产品推荐
相关产品推荐

