Reputation: 253
I'm trying to do the following cURL call in a c# .net environment
curl -XPOST -d 'Metadata/Type = "sas"' http://bms.org/bcknd/republish
The C# code is as follows:
var requestContent = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Metadata/Type", "\"sas\""), });
HttpResponseMessage response = await client.PostAsync("http://bms.org/bcknd/republish", requestContent);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
I'm getting a 400 Bad request and when I print it out. Maybe it has something to do with the -XPOST and -d parameter from the curl call?
EDIT: Here's the http request from curl:
POST http://bms.org/bcknd/republish HTTP/1.1
Host: bms.org/bcknd
User-Agent: curl/7.48.0
Accept: */*
Content-Length: 43
Content-Type: application/x-www-form-urlencoded
Metadata/Type = "sas"
Here's the http request from my code:
POST http://bms.org/bcknd/republish HTTP/1.1
Accept: */*
User-Agent: curl/7.48.0
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: bms.org/bcknd
Content-Length: 43
Connection: Keep-Alive
Metadata/Type = "sas"
Upvotes: 1
Views: 1182
Reputation: 131228
Short Version
Post the data as StringContent
without url encoding and check the response status before trying to read the response body. Make sure the call completes before the application exits, otherwise the call will be cancelled when the application exits. That means, use async Task
in Main
, not async void
:
class Program
{
static async Task Main(string[] args)
{
var client=new HttpClient();
var data = new StringContent("Metadata/Type=\"sas\"",Encoding.UTF8,"application/x-www-form-urlencoded");
var response = await client.PostAsync("http://www.google.com/bcknd/republish", data);
if(response.IsSuccessStatusCode)
{
var responseContent = response.Content;
var body=await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
else
{
Console.WriteLine($"Oops! {response.StatusCode} - {response.ReasonPhrase}");
}
}
}
Explanation
In cases like this it's very important to know what's actually being sent. To do that, one can use a debugging proxy like Fiddler or Charles.
Curl with -d
sends unencoded data. This call :
curl -XPOST -d 'Metadata/Type = "sas"' http://bms.org/bcknd/republish
will send :
POST http://www.google.com/bcknd/republish HTTP/1.1
Host: www.google.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
Metadata/Type = "sas"
/
and "
would have been replaced with other characters if URL encoding was applied. Note also the User-Agent
and Accept
headers
If --data-urlencode
is used, the value will be URL encoded :
POST http://www.google.com/bcknd/republish HTTP/1.1
Host: www.google.com
User-Agent: curl/7.55.1
Accept: */*
Connection: Keep-Alive
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
Metadata/Type =%20%22sas%22
This code on the other hand :
static async Task Main(string[] args)
{
var client=new HttpClient();
var data = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Metadata/Type", "\"sas\""), });
var response = await client.PostAsync("http://www.google.com/bcknd/republish", data);
var responseContent = response.Content;
var body=await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
Will send :
POST http://www.google.com/bcknd/republish HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Host: www.google.com
Metadata%2FType=%22sas%22
To get the original payload, one can use StringContent
with hand-coded content:
var data = new StringContent("Metadata/Type= \"sas\"",Encoding.UTF8,"application/x-www-form-urlencoded");
The request is :
POST http://www.google.com/bcknd/republish HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 19
Host: www.google.com
Metadata/Type= "sas"
If you want to send the User-Agent
and Accept
headers, you can add them to each individual message or as default request headers :
var client=new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("curl","7.55.1"));
These will add :
Accept: */*
User-Agent: curl/7.55.1
to the request
Upvotes: 3
Reputation: 7866
You can call remote URL as following using HttpClient
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://bms.org/bcknd/republish"))
{
request.Content = new StringContent("Metadata/Type = \"sas\"", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await httpClient.SendAsync(request);
}
}
Here I have just added reference code, by using that you can create your own. I checked your curl request and it seems issue it self.
Upvotes: 0