Skip to main content

Command Palette

Search for a command to run...

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

Sometimes you need to ping some endpoints. Don't rely on HttpClient, but use the native Ping class.

Published
2 min read
C# Tip: use the Ping class instead of an HttpClient to ping an endpoint
D

I’m a Principal Backend Developer with more than 10 years of professional experience. I’ve been working with Microsoft platforms and frameworks since 2014.

I’ve worked with many tools and frameworks, such as Azure, MongoDB, Docker, and, of course, .NET and C#. I love learning new things, and I think that the best way to learn is to share: that’s why I started my journey as a content creator and conference speaker.

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 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 in the comment section below.

🐧

172 views
C
C0deR4t3y ago

It's important to know that many websites / environments turn off ICMP replies (replying to PING commands). If the host refuses to reply to your echo/ping request it might seem like the host is down when in actual fact it is up but does not support the use of PING

Other than that, great article, enjoyable read 🐼

D

I've never understood why they turn off ICMP.

BTW in some environments, such as the Azure Portal, you can use the tcpping command (here, in an old article)

More from this blog

C

Code4IT

78 posts

Code4IT, by Davide Bellone, is a blog for backend developers covering .NET, Azure, Software Architecture, Testing strategies, tools, and more, all with a straight-to-the-point approach.