# How to Use a HttpClient Proxy in C# (2026)

> Learn how to use a proxy with HttpClient to avoid IP blocks and scrape in C# quickly and effectively.

Source: https://www.zenrows.com/blog/httpclient-proxy-c-sharp

HttpClient is one of the best libraries for making HTTP requests in .NET, enabling [web scraping in C#](/blog/web-scraping-c-sharp). However, your automated requests may get identified as coming from a bot and blocked, so let's learn how to avoid that with a C# HttpClient proxy!

## What Is an HttpClient Proxy
An HttpClient proxy acts as an intermediary between your app and the target server. Its purpose is to route requests made by the HTTP C# client through a different IP address so that the server will see them as coming from the proxy server instead of the original client.

This mechanism is useful to avoid getting blocked and bypassing geographical restrictions. Read on to find out how to implement it!

## Prerequisites
If you don't have .NET installed on your machine, [download the latest version of SDK](https://dotnet.microsoft.com/en-us/download/dotnet/7.0). Double-click on the installer and follow the wizard.

To save time, you can install the [.NET Coding Pack](https://code.visualstudio.com/docs/languages/dotnet#_net-coding-pack), including the .NET SDK, Visual Studio Code, and its .NET extensions.

Open PowerShell and verify that .NET works:

```nginx
dotnet --list-sdks
```

It should print something like this:

```nginx
7.0.5 [C:\Program Files\dotnet\sdk]
```

Next, follow the instructions below from the [official guide](https://learn.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-7-0) to set up a C# project in Visual Studio Code:

1. Create a folder for your project:

```nginx
mkdir HttpClientProxy
```

2. Open it in Visual Studio Code.
3. Initialize a .NET project with the command below in the VS Code terminal:

```nginx
dotnet new console --framework net7.0
```

The `HttpClientProxy` folder now contains a C# app. [HttpClient](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-7.0) is part of the C# system library, so you don't need to add it as an external package.

Use it to perform a basic HTTP request to [HttpBin](https://httpbin.org/ip) to get your IP by updating `Program.cs` as follows. The [`GetAsync()`](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getasync?view=net-7.0) sends an HTTP GET request to the specified URL as an asynchronous operation. `using` makes sure the resources allocated for the request are released when no longer needed. Then, [`ReadAsStringAsync()`](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync?view=net-7.0#system-net-http-httpcontent-readasstringasync) gets the response returned by the server as a string.

<!-- program.cs -->
```nginx
using System.Net;

namespace HttpClientProxy
{
  class Program
  {  
    static async Task Main(string[] args)
    {
      // initialize an HttpClient instance
      HttpClient client = new HttpClient();

      try
      {
        // perform an async GET request to HttpBin
        using HttpResponseMessage response = await client.GetAsync("https://httpbin.org/ip");
        // extract the request response and print it
        string responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseContent);
      }
      catch (HttpRequestException e)
      {
        Console.WriteLine("Request failed with error: ", e.Message);
      }

    }
  }
}
```

This script will print your IP:

```json
{
  "origin": "194.127.58.110"
}
```

Fantastic! You learned how to get started with HttpClient and are ready to use it with a proxy!

> **Skip the blocks.** [Try Zenrows free](/) and get clean web data without the anti-bot fight.

## How to Use a Proxy with HttpClient in C#
First, get a valid proxy from [Free Proxy List](https://free-proxy-list.net/)  and store its URL in a string variable:

```nginx
string proxyURL = "http://103.167.135.111:80"
```

As you can see, a free proxy URL follows the syntax below:

```nginx
<PROXY_PROTOCOL>://<PROXY_IP_ADDRESS>:<PROXY_PORT>
```

By default, HttpClient reads the proxy configuration from the system settings. Change that behavior and set a proxy with a [`WebProxy`](https://learn.microsoft.com/en-us/dotnet/api/system.net.webproxy?view=net-7.0) instance like this:

<!-- program.cs -->
```nginx
// proxy configs
String proxyURL = "http://103.167.135.111:80";
WebProxy webProxy = new WebProxy(proxyURL);
// make the HttpClient instance use a proxy
// in its requests
HttpClientHandler httpClientHandler = new HttpClientHandler
{
  Proxy = webProxy
};
client = new HttpClient(httpClientHandler);
```

> **Note**
>
> [`HttpClientHandler`](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler?view=net-7.0) allows you to configure a variety of options for HttpClient, including proxies

Here's what the entire code looks like:

<!-- program.cs -->
```nginx
using System.Net;

namespace HttpClientProxy
{
  class Program
  {
    static async Task Main(string[] args)
    {
      string proxyURL = "http://103.167.135.111:80";
      WebProxy webProxy = new WebProxy(proxyURL);

      HttpClientHandler httpClientHandler = new HttpClientHandler
      {
        Proxy = webProxy
      };
      HttpClient client = new HttpClient(httpClientHandler);

      try
      {
        using HttpResponseMessage response = await client.GetAsync("https://httpbin.org/ip");
        string responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseContent);
      }
      catch (HttpRequestException e)
      {
        Console.WriteLine("Request failed with error: ", e.Message);
      }
    }
  }
}
```

Launch the script, and you'll get the following output:

```json
{
  "origin": "103.167.135.111"
}
```

That's the exact same IP of the proxy server, meaning the HttpClient is making requests through the specified proxy, as desired.

Perfect! You now know the basics of using a C# HttpClient proxy. It's time to explore more advanced concepts!

## Proxy Authentication with HttpClient: Username & Password
Premium proxies protect their access through authentication. That way, only users with a valid pair of credentials can connect to their servers.

The URL of an authenticated proxy involves a username and a password. This is the usual syntax:

```nginx
<PROXY_PROTOCOL>://<YOUR_USERNAME>:<YOUR_PASSWORD>@<PROXY_IP_ADDRESS>:<PROXY_PORT>
```

Yet, `WebProxy` doesn't support it and instead requires a [`Credentials`](https://learn.microsoft.com/en-us/dotnet/api/system.net.webproxy.credentials?view=net-7.0#system-net-webproxy-credentials) instance:

<!-- program.cs -->
```nginx
WebProxy webProxy = new WebProxy
{
  // proxy URL with no credentials involved
  Address = new Uri("<PROXY_URL>"),
  // specify the proxy credentials
  Credentials = new NetworkCredential(
        userName: "<YOUR_USERNAME>",
        password: "<YOUR_PASSWORD>"
  )
};
```

Here's a complete example of how to use proxy authentication in HttpClient:

<!-- program.cs -->
```nginx
using System.Net;

namespace HttpClientProxy
{
  class Program
  {
    static async Task Main(string[] args)
    {
      // authenticated proxy info
      string proxyURL = "http://139.92.119.185:8080";
      string proxyUsername = "jiprkcdaumui";
      string proxyPassword = "tZqqUck4D5VSczwFU";

      WebProxy webProxy = new WebProxy
      {
        Address = new Uri(proxyURL),
        // specify the proxy credentials
        Credentials = new NetworkCredential(
              userName: proxyUsername,
              password: proxyPassword
        )
      };

      HttpClientHandler httpClientHandler = new HttpClientHandler
      {
        Proxy = webProxy
      };
      HttpClient client = new HttpClient(httpClientHandler);

      try
      {
        using HttpResponseMessage response = await client.GetAsync("https://httpbin.org/ip");
        string responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseContent);
      }
      catch (HttpRequestException e)
      {
        Console.WriteLine("Request failed with error: ", e.Message);
      }
    }
  }
}
```

The proxy server will respond with a [`407: Proxy Authentication Required`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407) error when the credentials are invalid. The request will fail, and HttpClient will raise an `HttpRequestException` stating:

```nginx
The remote server returned an error: (407) Proxy Authentication Required.
```

To avoid that, make sure the proxy username and password are correct.

## Use a Rotating Proxy with HttpClient in C#
Even if you protect your IP with a proxy, the target server can still block your script if you make too many requests. The good news is you can avoid that with a rotating proxy approach.

That method involves using a new proxy after a specified period or number of requests, or randomly. Your end IP will keep changing, making the server unable to track you. That's the main advantage of an HttpClient proxy rotator!

Let's learn how to do so in C#.

### Rotate IPs with a Free Solution
First, retrieve a pool of free proxies and store them in a list:

<!-- program.cs -->
```nginx
List<string> proxies = new List<string>
{
  "http://129.151.91.248:80",
  "http://18.169.189.181:80",
  // ...
  "http://212.76.110.242:80"
};
```

Then, define a function to execute a `GET` request through a rotating proxy. You'll extract a random proxy from the pool and use it to instantiate an `HttpClient` object, to then perform a GET request to the URL passed as a parameter.

<!-- program.cs -->
```nginx
static async Task<HttpResponseMessage> MakeRequestUsingRandomProxy(List<string> proxies, string url)
{
  // extract a random proxy from the list
  Random random = new Random();
  int index = random.Next(proxies.Count);
  string proxyURL = proxies[index];
  
  // set the proxy
  WebProxy webProxy = new WebProxy(proxyURL);
  HttpClientHandler handler = new HttpClientHandler()
  {
    Proxy = new WebProxy(proxyURL)
  };

  // make the request with the random proxy
  using (HttpClient client = new HttpClient(handler))
  {
    return await client.GetAsync(url);
  }
}
```

You can use `MakeRequestUsingRandomProxy` as below to randomize the proxy selection for each request. Every time you run the function below, you'll get a different IP.

<!-- program.cs -->
```nginx
HttpResponseMessage response = await MakeRequestUsingRandomProxy(proxies, "https://httpbin.org/ip");
string responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
```

Awesome! You built a proxy rotator, but it has a couple of issues:

1.  **It relies on free proxies:** We used them to learn the basics, but you should never rely on them because they're failure-prone, slow, and get you blocked most of the time. Instead, take a look at our list of the [best proxy types for scraping](/blog/web-scraping-proxy).
2.  **It instantiates several HttpClient times:** Every time the function gets called, it creates a new HttpClient instance. The [documentation advises against it](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-7.0#instancing). The reason is that HttpClient allocates a lot of sockets per instance, not disposing them for future reuse.

Thus, that script is unreliable and resource-intensive. You may think of caching an HttpClient instance and updating its proxy configurations. The library doesn't support that, so there isn't an easy fix for the resource leak.

To address the issues, you need to use commercial proxies and handle HttpClient instances with [**`IHttpClientFactory`**](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.ihttpclientfactory?view=dotnet-plat-ext-7.0&viewFallbackFrom=net-7.0), although it may end up being expensive and unnecessarily complex.

The real solution? A premium scraping proxy like Zenrows.

### Premium Proxy to Avoid Getting Blocked
Free proxies are unreliable for web scraping due to their frequent downtime, security risks, and low IP reputation. They often get blocked quickly, making them unsuitable for production use.

Premium proxies provide a more reliable solution for avoiding blocks. Using a premium proxy service with features like IP rotation and geo-targeting can significantly improve your scraping success rate.

[Zenrows' Residential Proxies](/products/fetch) is an excellent premium proxy provider that offers a network of 55M+ IPs across 185+ countries. With features like dynamic IP rotation, intelligent proxy selection, geo-targeting, and 99.9% network uptime, it's ideal for web scraping needs.

Let's see how to implement Zenrows' residential proxy feature with HttpClient.

[Sign up](https://app.zenrows.com/register?prod=residential_proxies) and navigate to the [Zenrows Proxy Generator](https://app.zenrows.com/proxies/generator). Your proxy credentials (username, password, proxy domain, and proxy port) will be generated automatically. You can further customize it according to your requirements.

![generate residential proxies with zenrows](/blog/_img/zenrows-proxy.png)

Since you've seen how to set proxies with authentication earlier in this tutorial, replace the placeholders with your generated proxy credentials in the following code:

```nginx
using System.Net;

namespace HttpClientProxy
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // replace the placeholders
            string proxyURL = "https://superproxy.zenrows.com:1338";
            string proxyUsername = "<ZENROWS_PROXY_USERNAME>";
            string proxyPassword = "<ZENROWS_PROXY_PASSWORD>";

            WebProxy webProxy = new WebProxy
            {
                Address = new Uri(proxyURL),
                // specify the proxy credentials
                Credentials = new NetworkCredential(
                    userName: proxyUsername,
                    password: proxyPassword
              )
            };

            HttpClientHandler httpClientHandler = new HttpClientHandler
            {
                Proxy = webProxy
            };
            HttpClient client = new HttpClient(httpClientHandler);

            try
            {
                using HttpResponseMessage response = await client.GetAsync("https://httpbin.io/ip");
                string responseContent = await response.Content.ReadAsStringAsync();
                Console.WriteLine(responseContent);
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine("Request failed with error: ", e.Message);
            }
        }
    }
}
```

Here's the result after running the code 2 times:

<!-- program.cs -->
```nginx
# request 1
{
  "origin": "134.22.58.66:49028"
}
# request 2
{
  "origin": "185.200.236.135:29849"
}
```

Congratulations! The output confirms your request was routed through Zenrows Residential Proxies. Your scraper is now using high-quality proxies that are less likely to get blocked.

## Conclusion
This step-by-step tutorial explained how to configure a proxy in HttpClient. You began with the basics and have become an HttpClient Proxy C# ninja!

Now  you know:

-   What an HttpClient proxy is.
-   The basics of setting a proxy in C#.
-   How to deal with an authenticated proxy with HttpClient.
-   How to build a rotating proxy, why this solution doesn't work with free proxies, and what the best practices are.

Remember that proxies help you avoid IP blocks, but advanced anti-scraping technologies like Cloudflare can still detect you. The solution is Zenrows, a scraping tool with anti-bot bypass features and the best rotating residential proxies. [Try it for free today](/)!
