cURL to C#

Convert a cURL command into a C# HttpClient request.

cURL Command
C# (HttpClient) Output
C# (HttpClient) code appears here

Related Tools

Documentation

What is curl-to-C#?

This tool converts a curl command into C# code using System.Net.Http.HttpClient — the standard HTTP client in the .NET base class library, requiring no NuGet package for the request itself.

How it works

The same curl parser used by every converter on this site extracts method, URL, headers, body, form fields, and auth. Because the target HTTP method can be anything a curl command specifies — not just GET or POST — the generator always builds an explicit HttpRequestMessage with new HttpMethod("...") rather than reaching for a per-verb convenience method like GetAsync. The body becomes a StringContent built from the raw -d value, never re-parsed as JSON, so what curl would send and what the C# code sends match exactly. -u user:pass becomes an AuthenticationHeaderValue("Basic", ...) computed from Convert.ToBase64String(Encoding.UTF8.GetBytes(...)) at the top of the method.

Features

  • Zero NuGet dependencies — System.Net.Http.HttpClient ships with .NET
  • Handles any HTTP method via HttpRequestMessage + HttpMethod, not just GET/POST
  • Body passed through as a raw string, not re-encoded
  • -u Basic Auth computed via Convert.ToBase64String
  • -F/--form uploads become MultipartFormDataContent, with file fields stubbed for a real FileStream

Example

Input: curl -X POST https://api.example.com/v1/users -H "Content-Type: application/json" -d '{"name":"Alice"}'

Output:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");

        var content = new StringContent("{\"name\":\"Alice\"}", Encoding.UTF8);
        var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.example.com/v1/users") { Content = content };

        var response = await client.SendAsync(request);
        var body = await response.Content.ReadAsStringAsync();

        Console.WriteLine((int)response.StatusCode);
        Console.WriteLine(body);
    }
}

Common errors

Setting Content-Type via client.DefaultRequestHeaders works for most headers, but HttpClient is notoriously strict about a small set of headers (like Content-Type and Content-Length) that technically belong on the request's content, not the client or message — TryAddWithoutValidation is used here specifically to avoid a InvalidOperationException that Headers.Add would throw for exactly that reason.

Best practices

Reuse a single HttpClient instance across requests in real applications rather than a using-scoped one per call as shown here — the well-documented .NET socket-exhaustion issue comes from creating and disposing many short-lived HttpClient instances, and IHttpClientFactory is the standard fix in ASP.NET Core apps.

Frequently Asked Questions

Does this need a NuGet package?

No — System.Net.Http.HttpClient has shipped in .NET itself since .NET Framework 4.5 and every version of .NET Core/.NET 5+, so the generated code needs nothing beyond the base class library.

How is multipart/form-data (-F) handled?

Real fields become MultipartFormDataContent entries via StringContent. File fields get a TODO comment pointing at File.OpenRead(...) wrapped in a StreamContent, since this generator has no access to your actual filesystem to read real file bytes from.

How is Basic Auth handled?

Via Convert.ToBase64String(Encoding.UTF8.GetBytes(...)), set as an AuthenticationHeaderValue("Basic", credentials) on the client's default request headers — the standard HttpClient pattern for Basic Auth, since there's no dedicated "basic auth" constructor argument.

Why HttpRequestMessage instead of client.PostAsync/GetAsync?

Because the request's HTTP method comes from a curl flag at generation time (-X PATCH, -X DELETE, anything), not a fixed choice — HttpRequestMessage with new HttpMethod(...) handles an arbitrary method uniformly instead of picking a different HttpClient convenience method per verb.