5

I have a curl request that looks like this:

curl -i -XPOST 'http://my_url:port/write?db=myDb' -u user:xxxxx --data-binary 'FieldName,host=M.233 value=52.666 timestamp'

I'm trying to post this request using HttpClient. I'm not sure how exactly I should call it. This is what I tried to do:

public async void  TestHttpClient()
{ 
    var client = new HttpClient();
    var credentials = Encoding.ASCII.GetBytes("user:xxxxx");
    var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
    client.DefaultRequestHeaders.Authorization = header;
    client.BaseAddress = new Uri("http://my_url:port/write?db=myDb");
    var result = await client.PostAsync(..);
}

Which parameters should I write for PostAsync()?

How to convert --data-binary and FieldName,host=M.233 value=52.666 timestamp from curl to HttpClient?

Pikoh
  • 7,582
  • 28
  • 53
Sonja
  • 316
  • 1
  • 4
  • 13
  • 3
    Why don't you just set the `Credentials` property instead of trying to construct the authentication headers? – Panagiotis Kanavos Apr 12 '17 at 15:34
  • I'm new to C# and HttpClient so this is what I have fount on internet and tried to build my own looking to other questions and examples and trying to understand how it's working and what's the right way to convert my curl request. So as this is just my try, I'm opened for all the suggestions to find the best solution. – Sonja Apr 12 '17 at 15:40

4 Answers4

5

There is a lovely curl to c# converter which will convert your curl script to C# code using HTTPClient. https://curl.olsh.me/

Using this tool and your curl script provided we get the following result.

using (var httpClient = new HttpClient())
{
    using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://http//my_url:port/write?db=myDb"))
    {
        var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("user:xxxxx"));
        request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); 

        request.Content = new StringContent("FieldName,host=M.233 value=52.666 timestamp");
        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); 

        var response = await httpClient.SendAsync(request);
    }
}
timothy
  • 568
  • 8
  • 9
  • This website uploads your curl command to its server, you should not paste curl commands with sensitive data in them (such as cookies). – Boris Verkhovskiy Oct 17 '22 at 08:33
4

The solution for me was:

public async Task TestHttpClient()
{ 
    var client = new HttpClient();
    var credentials = Encoding.ASCII.GetBytes("user:xxxxx");
    var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
    client.DefaultRequestHeaders.Authorization = header;
    String url = "http://my_url:port/write?db=myDb";
    String content = "FieldName,host=M.233 value=52.666 timestamp";
    StringContent stringContent = new StringContent(content);
    var result = await client.PostAsync(url, stringContent);
}
Jace Rhea
  • 4,982
  • 4
  • 36
  • 55
Sonja
  • 316
  • 1
  • 4
  • 13
  • 1
    You should not have `async void`. That's a terrible idea. Have it return a Task instead. http://tomasp.net/blog/csharp-async-gotchas.aspx/ – mason Sep 29 '17 at 20:49
  • Thank you for the info. Actually I used Task in the app, just forgot to correct it here in the answer as I copied this part of code from the question. Now I corrected the answer. – Sonja Sep 29 '17 at 21:11
  • Also, creating HttpClient instances like that can be dangerous. See [You're Using HttpClient Wrong And It's Destabilizing Your Software](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/). I personally avoid using HttpClient and have found [RestSharp](http://restsharp.org/) to be a much easier tool to use. – mason Sep 29 '17 at 23:07
0

To get pass the --data-binary flag I did have to add Content-Transfer-Encoding to request content header, see following example:

curl:

curl -v -X POST \
    -H "Authorization: Bearer token" \
    --header "Content-Type: application/json" \
    --data-binary "@example.json" \
    https://example.com/data

C#:

using var httpClient = new HttpClient
{
    BaseAddress = "https://example.com/"
};
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
const string Uri = "data";
var stringContent = new StringContent(jsonString, Encoding.UTF8, "application/json"); // In case data is json (ex: --header "Content-Type: application/json"):
stringContent.Headers.Add("Content-Transfer-Encoding", "binary"); // For data-binary flag: --data-binary "@example.json"
var request = new HttpRequestMessage(HttpMethod.Post, Uri) { Content = stringContent };
var response = await httpClient.SendAsync(request, cancellationToken);
ols
  • 1
0

Paste your command into curlconverter.com/csharp/ and it will convert it into

using System.Net.Http.Headers;

HttpClient client = new HttpClient();

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://my_url:port/write?db=myDb");

request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("user:xxxxx")));

request.Content = new StringContent("FieldName,host=M.233 value=52.666 timestamp");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");

HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103