برچسب: HttpClient

  • C# Tip: use the Ping class instead of an HttpClient to ping an endpoint

    C# Tip: use the Ping class instead of an HttpClient to ping an endpoint


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    What if you wanted to see if a remote website is up and running?

    Probably, the first thing that may come to your mind is to use a common C# class: HttpClient. But it may cause you some trouble.

    There is another way to ping an endpoint: using the Ping class.

    Why not using HttpClient

    Say that you need to know if the host at code4it.dev is live. With HttpClient you might use something like this:

    async Task Main()
    {
        var url = "https://code4it.dev";
    
        var isUp = await IsWebsiteUp_Get(url);
    
        Console.WriteLine("The website is {0}", isUp ? "up" : "down");
    }
    
    private async Task<bool> IsWebsiteUp_Get(string url)
    {
        var httpClient = new HttpClient(); // yes, I know, I should use HttpClientFactory!
        var httpResponse = await httpClient.GetAsync(url);
        return httpResponse.IsSuccessStatusCode;
    }
    

    There are some possible issues with this approach: what if there is no resource available in the root? You will have to define a specific path. And what happens if the defined resource is under authentication? IsWebsiteUp_Get will always return false. Even when the site is correctly up.

    Also, it is possible that the endpoint does not accept HttpGet requests. So, we can use HttpHead instead:

    private async Task<bool> IsWebsiteUp_Head(string url)
    {
        var httpClient = new HttpClient();
        HttpRequestMessage request = new HttpRequestMessage
        {
            RequestUri = new Uri(url),
            Method = HttpMethod.Head // Not GET, but HEAD
        };
        var result = await httpClient.SendAsync(request);
        return result.IsSuccessStatusCode;
    }
    

    We have the same issues described before, but at least we are not bound to a specific HTTP verb.

    By the way, we need to find another way.

    How to use Ping

    By using the Ping class, we can get rid of those checks and evaluate the status of the Host, not of a specific resource.

    private async Task<bool> IsWebsiteUp_Ping(string url)
    {
        Ping ping = new Ping();
        var hostName = new Uri(url).Host;
    
        PingReply result = await ping.SendPingAsync(hostName);
        return result.Status == IPStatus.Success;
    }
    

    The Ping class comes in the System.Net.NetworkInformation namespace, and allows you to perform the same operations of the ping command you usually send via command line.

    Conclusion

    We’ve seen why you should use Ping instead of HttpClient to perform a ping-like operation.

    There’s more than this: head to this more complete article to learn more.

    👉 Let’s discuss it on Twitter or on the comment section below.

    🐧





    Source link

  • C# Tip: use IHttpClientFactory to generate HttpClient instances

    C# Tip: use IHttpClientFactory to generate HttpClient instances


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    The problem with HttpClient

    When you create lots of HttpClient instances, you may incur Socket Exhaustion.

    This happens because sockets are a finite resource, and they are not released exactly when you ‘Dispose’ them, but a bit later. So, when you create lots of clients, you may terminate the available sockets.

    Even with using statements you may end up with Socket Exhaustion.

    class ResourceChecker
    {
        public async Task<bool> ResourceExists(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                var response = await client.GetAsync(url);
                return response.IsSuccessStatusCode;
            }
        }
    }
    

    Actually, the real issue lies in the disposal of HttpMessageHandler instances. With simple HttpClient objects, you have no control over them.

    Introducing HttpClientFactory

    The HttpClientFactory class creates HttpClient instances for you.

    class ResourceChecker
    {
        private IHttpClientFactory _httpClientFactory;
    
        public ResourceChecker(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }
    
        public async Task<bool> ResourceExists(string url)
        {
            HttpClient client = _httpClientFactory.CreateClient();
            var response = await client.GetAsync(url);
            return response.IsSuccessStatusCode;
        }
    }
    

    The purpose of IHttpClientFactory is to solve that issue with HttpMessageHandler.

    An interesting feature of IHttpClientFactory is that you can customize it with some general configurations that will be applied to all the HttpClient instances generated in a certain way. For instance, you can define HTTP Headers, Base URL, and other properties in a single point, and have those properties applied everywhere.

    How to add it to .NET Core APIs or Websites

    How can you use HttpClientFactory in your .NET projects?

    If you have the Startup class, you can simply add an instruction to the ConfigureServices method:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
    }
    

    You can find that extension method under the Microsoft.Extensions.DependencyInjection namespace.

    Wrapping up

    In this article, we’ve seen why you should not instantiate HttpClients manually, but instead, you should use IHttpClientFactory.

    Happy coding!

    🐧



    Source link