c# 如何调用 rest api

最稳妥的 HttpClient 用法是复用而非每次新建,应声明为静态字段或 DI 单例;GET 请求需用 EnsureSuccessStatusCode() 处理错误状态码,POST JSON 必须设置 Content-Type,认证信息应通过 DefaultRequestHeaders 预设,错误处理需兼顾网络异常与 HTTP 状态码。

c# 如何调用 rest api

HttpClient 发起 GET 请求最稳妥

直接 new HttpClient 是常见错误起点——它本应复用,而非每次请求都新建。长期运行的服务若频繁创建销毁,会耗尽 socket 连接,触发 SocketExceptionHttpRequestException: Connection refused。推荐将 HttpClient 声明为静态字段或通过 DI 注册为单例。

基础 GET 示例:

var client = new HttpClient();
var response = await client.GetAsync("https://api.example.com/users");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
  • EnsureSuccessStatusCode() 会抛出异常(如 404/500),避免手动检查 response.IsSuccessStatusCode
  • 若需设置超时,用 client.Timeout = TimeSpan.FromSeconds(10);,别在 GetAsync 外套 Task.Wait()Task.Result
  • GET 参数建议用 Uri.EscapeDataString() 手动拼接,或借助 FormUrlEncodedContent + PostAsync 模拟(不推荐);更安全的是用 HttpClient.BaseAddressstring.Concat() 构建完整 URI

POST JSON 数据必须设对 Content-Type

发 JSON 到 REST API 时,漏设 Content-Type: application/json 是 400 Bad Request 的头号原因。.NET 6+ 可用 JsonSerializer.SerializeToUtf8Bytes() 避免字符串编码开销;老版本建议用 StringContent 并显式指定编码。

示例(兼容 .NET 5+):

本地宝团购导航网站

本地宝团购导航网站

本地宝团购导航网站v1.2是由本地宝提供API接口调取团购数据,使用本程不用管理接口、数据采集,只需将程序放在网站某文件夹或域名下。程序是经过SEO优化,对提升网站流量有很大帮助,如果你的网站支持rewrite伪静态的话,你可以开启伪静态功能。 后台使用 后台地址:http://域名/admin 帐号密码:jiahai jiahai

下载

var client = new HttpClient();
var data = new { name = "Alice", email = "a@example.com" };
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.example.com/users", content);
  • 不要用 content.Headers.ContentType = new MediaTypeHeaderValue(...) 覆盖 StringContent 构造时已设的类型
  • 若 API 要求 application/json; charset=utf-8StringContent 默认已包含,无需额外处理
  • 大对象 POST 建议用 StreamContent + FileStream 流式上传,避免内存峰值

带认证的请求要小心 header 注入时机

Bearer Token、API Key 等认证信息必须在发起请求前写入 client.DefaultRequestHeaders,而不是每次调用 PostAsync 时临时加——后者在并发场景下可能被覆盖或遗漏。

  • Token 过期需刷新?别在 DefaultRequestHeaders.Authorization 里硬编码,改用 DelegatingHandler 拦截重试逻辑
  • Basic Auth 推荐用 Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pass}")) 生成 credential,再设为 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64)
  • 某些 API(如 GitHub)要求 User-Agent header,漏掉会返回 403;可统一加client.DefaultRequestHeaders.UserAgent.ParseAdd("myapp/1.0")

错误处理不能只靠 try-catch

HttpRequestException 只覆盖网络层失败(DNS 错、连接断),但 HTTP 状态码如 401、422、503 会进到 response.IsSuccessStatusCode == false 分支。忽略这点,会导致业务逻辑把错误响应当成功数据解析。

  • 统一检查 response.StatusCode:401 走登录刷新,422 解析 response.Content 提取 errors 字段,503 可考虑指数退避重试
  • 反序列化前务必确认 response.Content.Headers.ContentType?.MediaType == "application/json",否则 JsonSerializer.Deserialize() 可能抛 JsonException
  • 日志中记录 response.RequestMessage?.RequestUriresponse.StatusCode,但切勿打 response.Content.ReadAsStringAsync() 的原始响应体(含敏感数据或超大 payload)

实际集成时,最难缠的是第三方 API 文档写得模糊:比如声称“返回 JSON”,实际空 body 时没设 Content-Type;或要求 PUT 但实现只认 PATCH。这些没法靠通用封装解决,得留一两个裸 HttpClient.SendAsync() 调用点,方便快速验证 raw request/response。

https://www.php.cn/faq/1982212.html

发表回复

Your email address will not be published. Required fields are marked *