使用HttpClient发起POST请求报错:TaskAwaiter.ThrowForNonSuccess
HttpClient POST请求报错排查与修复
问题根源分析
- JSON结构不匹配:发送端手动构造
{"data": [Alert数组]}格式的请求体,但接收端直接期望[Alert数组]作为请求体,导致模型绑定失败触发异常。 - HttpClient滥用:每次请求新建
HttpClient实例,易造成连接池耗尽,引发潜在异常。 - 语法错误:发送端代码中
string uri = ConfigurationManager.AppSettings["LinkPost"]缺失分号,属于基础语法问题。 - 无异常捕获:未对异步请求的异常进行捕获,无法获取具体错误详情。
修复方案
1. 修正JSON结构匹配问题
方案A:调整发送端,匹配接收端的参数格式
直接序列化List<Alert>作为请求体,无需手动拼接JSON:
public async Task<int> PostMIIData(List<Alert> data) { // 修复语法错误:添加分号 string uri = ConfigurationManager.AppSettings["LinkPost"]; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // 直接序列化List<Alert>,无需手动包裹data字段 var json = JsonConvert.SerializeObject(data); // 使用using确保HttpClient及时释放 using HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response = await client.PostAsync(uri, new StringContent(json, Encoding.UTF8, "application/json")); // 主动检查请求状态,抛出具体错误 response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); return 0; }
方案B:调整接收端,匹配发送端的JSON结构
如果必须保留{"data":...}的请求格式,需新增接收模型:
// 新增接收模型类 public class AlertDataWrapper { public List<Alert> Data { get; set; } } // 修改接收方法 [WebMethod()] [HttpPost] public static void PostDataMII([FromBody] AlertDataWrapper wrapper) { SqlManager sql = new SqlManager(); sql.PostMII(wrapper.Data); }
2. 优化HttpClient使用
避免每次请求新建实例,推荐使用全局单例或IHttpClientFactory(依赖注入场景):
// 全局单例示例 public static class HttpClientSingleton { public static readonly HttpClient Instance = new HttpClient(); static HttpClientSingleton() { Instance.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; } } // 调用时直接使用单例 var response = await HttpClientSingleton.Instance.PostAsync(uri, content);
3. 添加异常捕获与日志
捕获异常并输出具体信息,便于精准排查:
public async Task<int> PostMIIData(List<Alert> data) { try { string uri = ConfigurationManager.AppSettings["LinkPost"]; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var json = JsonConvert.SerializeObject(data); using HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response = await client.PostAsync(uri, new StringContent(json, Encoding.UTF8, "application/json")); response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); return 0; } catch (Exception ex) { // 记录日志,输出完整错误链 Console.WriteLine($"请求失败:{ex.Message}"); if (ex.InnerException != null) { Console.WriteLine($"内部错误详情:{ex.InnerException.Message}"); } throw; // 或根据业务需求返回错误码 } }
4. 验证基础配置
确认ConfigurationManager.AppSettings["LinkPost"]获取的地址与Fiddler测试时完全一致,包括协议(http/https)、端口、路径,避免地址错误导致请求失败。
内容的提问来源于stack exchange,提问作者Douglas Oliveira
相关产品推荐
相关产品推荐

