How do I make calls to a REST API using C#?

后端 未结 15 1626
面向向阳花
面向向阳花 2020-11-22 08:10

This is the code I have so far:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Net.Http;
usi         


        
15条回答
  •  鱼传尺愫
    2020-11-22 08:43

    The answer marked here suggests using HttpClient directly and the disposing of it. This might work, but it's quite easy to run in to problems with HttpClient if you don't use it correctly.

    If you're going to use HttpClient, you're better off handing over the creation/disposal of HttpClients to a third-party library that uses the factory pattern. RestClient.Net is one such library.

    It comes with a very basic HttpClient factory so that you don't run in to the socket exhaustion problem,

    public class DefaultHttpClientFactory : IHttpClientFactory, IDisposable
    {
        #region Fields
        private bool disposed;
        private readonly ConcurrentDictionary> _httpClients;
        private readonly Func> _createClientFunc;
        #endregion
    
        #region Constructor
        public DefaultHttpClientFactory() : this(null)
        {
        }
    
        public DefaultHttpClientFactory(Func> createClientFunc)
        {
            _createClientFunc = createClientFunc;
            _httpClients = new ConcurrentDictionary>();
    
            if (_createClientFunc != null) return;
            _createClientFunc = name =>
            {
                return new Lazy(() => new HttpClient(), LazyThreadSafetyMode.ExecutionAndPublication);
            };
        }
        #endregion
    
        #region Implementation
        public HttpClient CreateClient(string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
    
            return _httpClients.GetOrAdd(name, _createClientFunc).Value;
        }
    
        public void Dispose()
        {
            if (disposed) return;
            disposed = true;
    
            foreach (var name in _httpClients.Keys)
            {
                _httpClients[name].Value.Dispose();
            }
        }
        #endregion
    }
    

    But Microsoft's IHttpClientFactory implementation can also be used for the latest and greatest:

        var serviceCollection = new ServiceCollection();
        var baseUri = new Uri("http://www.test.com");
        serviceCollection.AddSingleton(typeof(ISerializationAdapter), typeof(NewtonsoftSerializationAdapter));
        serviceCollection.AddSingleton(typeof(ILogger), typeof(ConsoleLogger));
        serviceCollection.AddSingleton(typeof(IClient), typeof(Client));
        serviceCollection.AddDependencyInjectionMapping();
        serviceCollection.AddTransient();
    
        //Make sure the HttpClient is named the same as the Rest Client
        serviceCollection.AddSingleton(x => new Client(name: clientName, httpClientFactory: x.GetRequiredService()));
        serviceCollection.AddHttpClient(clientName, (c) => { c.BaseAddress = baseUri; })
            .AddHttpMessageHandler();
    
        var serviceProvider = serviceCollection.BuildServiceProvider();
        var client = serviceProvider.GetService();
        await client.GetAsync();
    
    

    RestClient.Net takes in to account dependency injection, mocking, IoC containers, unit testability, and above all is fast. I've hunted around and the only the other client that seems to work in a similar capacity is Flurl.Http.

    提交回复
    热议问题