API在Postman中可用但HTTP客户端调用失败,报400错误
问题描述
调用API时返回400 Bad Request错误,已配置CORS允许所有请求头,期望获得200状态码。
调用代码
public async Task<IActionResult> GenerateOTP(string Mobile) { try { StringContent jsonstr = new StringContent(JsonConvert.SerializeObject(new { Mobile = Mobile }), Encoding.UTF8, "application/json"); endPoint = _httpClient.BaseAddress + "User/OTPGenerate"; HttpResponseMessage response = await _httpClient.PostAsJsonAsync(endPoint, jsonstr); if(response.IsSuccessStatusCode) { return Content(response.Content.ToString()); } else { return Content("apifail"); } } catch(Exception ex) { return Content(ex.Message); } }
解决方案
核心问题是错误使用PostAsJsonAsync方法:
PostAsJsonAsync会自动将传入的对象序列化为JSON格式发送请求,不需要提前用JsonConvert.SerializeObject转成StringContent- 当前写法会导致双重序列化:先把匿名对象转成JSON字符串,
PostAsJsonAsync又会把这个字符串当作对象再次序列化,最终请求体格式完全不符合API要求,引发400错误
修改后的代码:
public async Task<IActionResult> GenerateOTP(string Mobile) { try { endPoint = _httpClient.BaseAddress + "User/OTPGenerate"; // 直接传入匿名对象,由PostAsJsonAsync自动处理序列化 HttpResponseMessage response = await _httpClient.PostAsJsonAsync(endPoint, new { Mobile = Mobile }); if(response.IsSuccessStatusCode) { // 原代码的response.Content.ToString()仅返回内容类型,需用ReadAsStringAsync()获取实际响应内容 var responseContent = await response.Content.ReadAsStringAsync(); return Content(responseContent); } else { return Content("apifail"); } } catch(Exception ex) { return Content(ex.Message); } }
额外补充两个细节:
- 调试时可以查看请求的实际内容(比如用Fiddler或HttpClient日志),确认请求体格式是否匹配API要求
- 若API要求的请求头有特殊规则,可通过
_httpClient.DefaultRequestHeaders提前配置
内容的提问来源于stack exchange,提问作者OMM
相关产品推荐
相关产品推荐

