C# HttpClient 和 API

huangapple go评论74阅读模式
英文:

C# HttpClient and API

问题

  1. HttpClient类用于从API获取数据是否是最佳选择?我从API获取一个字符串然后将其反序列化为对象。
  2. 每次使用HttpClient都会创建一个新实例(每个用户都会创建)。最佳做法是每个请求都使用 using (HttpClient client = new HttpClient()) 吗?

尝试找到最佳和最优解决方案。

英文:

I have a web application that pulls data from an API using the HttpClient class. I have a few questions.

  1. Is HttpClient optimal for getting data from API? I get a string from APi and deserialize it into an object.
  2. A new instance of HttpClient is created each time it is used (for each user). Is it best to use: using (HttpClient client = new HttpClient()) for each request?

Try to find best and optimal solution.

答案1

得分: 5

  1. 是的,HttpClient 绝对适用于使用 Web API 和反序列化。

  2. 对于每个请求都创建一个新的 HttpClient 不是一个好的用法。推荐的方式是使用 IHttpClientFactory 接口创建 HttpClient 对象。 以下是来自 MSDN 的基本用法示例:

class TodoService
{
    private readonly IHttpClientFactory _httpClientFactory = null!;
    private readonly ILogger<TodoService> _logger = null!;

    public TodoService(
        IHttpClientFactory httpClientFactory,
        ILogger<TodoService> logger) =>
        (_httpClientFactory, _logger) = (httpClientFactory, logger);

    public async Task<Todo[]> GetUserTodosAsync(int userId)
    {
        // 创建客户端
        using HttpClient client = _httpClientFactory.CreateClient();

        try
        {
            // 发送 HTTP GET 请求
            // 解析 JSON 响应并反序列化为 Todo 类型
            Todo[]? todos = await client.GetFromJsonAsync<Todo[]>(
                $"https://jsonplaceholder.typicode.com/todos?userId={userId}",
                new JsonSerializerOptions(JsonSerializerDefaults.Web));

            return todos ?? Array.Empty<Todo>();
        }
        catch (Exception ex)
        {
            _logger.LogError("获取有趣信息时发生错误:{Error}", ex);
        }

        return Array.Empty<Todo>();
    }
}

你可以参考以下链接了解更多信息:
IHttpClientFactory with .NET
以及
HttpClient 使用指南

英文:
  1. Yes, HttpClient is certainly appropriate for using web APIs and deserialization.

  2. Creating a new HttpClient for each request is not a good usage. The recommended way is to create HttpClient objects using the IHttpClientFactory interface. Here is a basic usage from MSDN:

     class TodoService
     {
         private readonly IHttpClientFactory _httpClientFactory = null!;
         private readonly ILogger&lt;TodoService&gt; _logger = null!;
    
         public TodoService(
             IHttpClientFactory httpClientFactory,
             ILogger&lt;TodoService&gt; logger) =&gt;
             (_httpClientFactory, _logger) = (httpClientFactory, logger);
    
         public async Task&lt;Todo[]&gt; GetUserTodosAsync(int userId)
         {
             // Create the client
             using HttpClient client = _httpClientFactory.CreateClient();
    
             try
             {
                 // Make HTTP GET request
                 // Parse JSON response deserialize into Todo types
                 Todo[]? todos = await client.GetFromJsonAsync&lt;Todo[]&gt;(
                     $&quot;https://jsonplaceholder.typicode.com/todos?userId={userId}&quot;,
                     new JsonSerializerOptions(JsonSerializerDefaults.Web));
    
                 return todos ?? Array.Empty&lt;Todo&gt;();
             }
             catch (Exception ex)
             {
                 _logger.LogError(&quot;Error getting something fun to say: {Error}&quot;, ex);
             }
    
             return Array.Empty&lt;Todo&gt;();
         }
     }
    

    }

You can refer to
IHttpClientFactory with .NET
and
Guidelines for using HttpClient

答案2

得分: 2

  1. 可以设置HTTP标头来压缩数据,以优化有效载荷大小,假设有gzip/brotli可用。

  2. HttpClient 不应每次都实例化,而是设计为单例。每个实例在操作系统级别打开套接字。一旦.NET处理完实例,需要一点时间才能完全关闭套接字,因此创建太多实例可能会导致通过HttpClient进行HTTP请求时对服务器造成拥塞。

英文:
  1. Yes, you can also set HTTP headers to compress the data to optimize payload size assuming gzip/brotli are available.

  2. The HttpClient is not meant to be instantiated per use. But, it is designed to be a singleton. Every instance opens up sockets at the OS level. Once .NET disposes of the instance it takes a bit for sockets to completely close so creating too many instances can choke the server making HTTP requests via HttpClient.

huangapple
  • 本文由 发表于 2023年4月7日 03:45:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定