商城首页欢迎来到中国正版软件门户

您的位置:首页 >C#怎么发送HTTP请求 C#如何使用HttpClient调用REST API接口获取数据【网络】

C#怎么发送HTTP请求 C#如何使用HttpClient调用REST API接口获取数据【网络】

  发布于2026-05-02 阅读(0)

扫一扫,手机访问

C#怎么发送HTTP请求 C#如何使用HttpClient调用REST API接口获取数据【网络】

C#怎么发送HTTP请求 C#如何使用HttpClient调用REST API接口获取数据【网络】

HttpClient 必须复用,不能每次 new

很多开发者踩的第一个坑,就是图省事,在方法里直接 new HttpClient()。这看似方便,实则后患无穷。频繁创建新实例,会导致底层套接字端口来不及释放,最终引发端口耗尽和恼人的 SocketException。不仅如此,每次新建连接,DNS解析缓存也无法复用,连接池的优势荡然无存,性能自然上不去。

那么,正确的复用姿势是什么?在 .NET Core 2.1 及更高版本中,最佳实践是通过依赖注入,使用 IServiceCollection.AddHttpClient() 将其注册为单例或作用域服务。如果是在控制台应用或简单的脚本里,一个简单有效的办法是将其声明为静态只读字段。

  • 典型的错误写法var client = new HttpClient(); 放在方法内部 —— 这意味着每次调用都会新建一个。
  • 推荐的静态复用写法private static readonly HttpClient _client = new HttpClient();
  • 额外提醒:除非你非常确定该实例的生命周期已经结束且后续绝不会再使用,否则不要手动去调用 _client.Dispose(),让框架来管理它。

GET 请求带参数要用 Uri.EscapeDataString 或 QueryHelpers

构建GET请求的查询字符串,是另一个高频出错点。直接进行字符串拼接,比如手写 ?key=value&key2=value2,一旦参数值里包含空格、中文、&、=这些特殊字符,整个URL结构就可能被破坏,导致服务端返回400错误或者解析异常。尤其是当参数值来自用户输入或数据库时,风险极高。

所以,别再手动拼接了。推荐使用 UriBuilder 配合 QueryHelpers(需要引用 Microsoft.AspNetCore.WebUtilities 包)来安全地构建URL。

  • 推荐方式示例
    var uri = new UriBuilder("https://api.example.com/users");
    uri.Query = QueryHelpers.AddQueryString("", new Dictionary {
        ["name"] = "张三",
        ["page"] = "1"
    });
    var response = await _client.GetAsync(uri.ToString());
  • 不推荐的做法:使用类似 $"https://...?name={name}" 的字符串插值。这种方式下,中文字符会变成乱码,而参数中的 & 符号更可能直接截断查询字符串,引发不可预知的问题。

POST JSON 数据必须设 Content-Type 并用 StringContent

发送POST请求提交JSON数据时,一个常见的疏忽是忘了设置正确的请求头。很多初学者会这样写:client.PostAsync(url, new StringContent(json, Encoding.UTF8)),结果服务端收到的虽然是一段JSON文本,但因为缺少 Content-Type: application/json 这个关键头信息,无法正确解析请求体,最终返回415 Unsupported Media Type错误。

  • 正确的完整写法应该是
    var json = JsonSerializer.Serialize(new { username = "alice", pwd = "123" });
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await _client.PostAsync("https://api.example.com/login", content);
  • 需要警惕的混淆:不要用 FormUrlEncodedContent 来发送JSON。这个类是为 application/x-www-form-urlencoded 格式设计的,它会将整个JSON字符串当作一个字段值进行编码,导致服务端完全无法解析出预期的对象结构。
  • 补充一点:如果调用的API要求Bearer Token认证,记得在发送请求前设置好请求头:_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

异步方法必须 await,别用 .Result 或 .Wait()

在异步编程模型里,阻塞异步任务是一个大忌。特别是在ASP.NET Core这类拥有同步上下文(SynchronizationContext)的Web应用环境中,在控制器里调用 task.Result.Wait() 极易引发线程死锁,导致应用无响应。HttpClient 的所有核心方法,如 GetAsyncPostAsync,都是真正的异步操作,必须用 await 关键字来驱动。

  • 绝对要避免的写法var res = client.GetAsync(url).Result; 或者 .Wait()
  • 在ASP.NET Core控制器中的正确做法:将Action方法标记为 async Task,并在方法体内使用 await
  • 在控制台程序中的处理:对于C# 7.1及以上版本,可以使用 static async Task Main(string[] args) 作为入口点。如果需要在其他地方同步等待,可以考虑使用 await MainAsync().ConfigureAwait(false) 来避免潜在的上下文问题。

说到底,使用HttpClient发送HTTP请求,真正的难点往往不在于“如何发送出去”,而在于背后的连接复用策略、参数编码的安全性以及异步流程的控制。这三个关键点如果没对齐,接口在测试时可能一切正常,一旦上线,间歇性的失败、缓慢的响应,甚至持续上涨的内存消耗,就会接踵而至。这才是问题的关键所在。

本文转载于:https://www.php.cn/faq/2334256.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注