I'm trying to do the equivalent of the following in C# ...
curl --request PUT \
--user-agent "Your Client Name/1.0" \
--header "Authorization: Basic YWRtaW46WW91ckFQSUtleUhlcmU=" \
--header "Content-Type: application/xml" \
--data-binary '<order><status_id>10</status_id></order>' \
https://www.example.com/api/v2/orders/101
My effort is giving my a 404 - Bad Request response. I've never looked at curl before.
Anyone out there have any ideas?
var url = String.Format("https://www.website.com/api/v2/orders/{0}", 1647);
var credentials = Convert.ToBase64String(
Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "admin", "mypassword")));
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "PUT";
request.Headers.Add(String.Format("Authorization: Basic {0}", credentials));
var status = "<?xml version='\"1.0'\" encoding='\"UTF-8'\"?><order><status_id>2<order><status_Id>";
using (var stream = request.GetRequestStream())
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(status);
}
}
var response = request.GetResponse();
Usually 'Bad request' is because the header is malformed:
look at
<?xml version='\"1.0'\" encoding='\"UTF-8'\"?>
it should be written as follow
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
with no ' or if you want to avoid escapes you could write
<?xml version='1.0' encoding='UTF-8'?>
Related
I am trying to convert a post request presented via cURL to c# HTTPClient with an old application using .NETFramework4
The cURL notation of the request from API docs:
curl -X POST -H 'Authorization: Token token=sfg999666t673t7t82' -H 'Content-Type: multipart/form-data' -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' -F file=#/Users/user1/Downloads/download.jpeg -F file_name=nameForFile -F is_shared=true -F targetable_id=1 -F targetable_type=Lead -X POST "https://domain.freshsales.io/api/documents"
My C# code, currently taking a file the user uploaded via input type form and trying to upload:
var filename = String.Format("status_{0}", DateTime.Now.ToString("dd/MM"));
using (var content = new MultipartFormDataContent())
{
content.Add(new ByteArrayContent(file), "file", filename);
content.Add(new StringContent(filename), "file_name");
content.Add(new StringContent("true"), "is_shared");
content.Add(new StringContent(uID), "targetable_id");
content.Add(new StringContent("Contact"), "targetable_type");
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, $"documents") { Content = content };
return client.SendAsync(req).Result;
}
For now I always get BadRequest(400)
In PostMan I am able to get OK(201)..
For more reference this is the code PostMan presents for C# RestSharp (not sure how to fully translate if to HttpClient + byteArrayContent..
var client = new RestClient("mydomain.io/api/documents");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Token token=xxx");
request.AddFile("file", "/Users/user1/Desktop/sc.png");
request.AddParameter("targetable_id", "134");
request.AddParameter("targetable_type", "Contact");
request.AddParameter("name", "a.jpg");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
I am trying to re-create a postman request in C#. Below a screenshot of the postman request that works:
(The header is application/json)
and the C# that does not:
[HttpGet]
[Route("GenerateAccessToken")]
[ProducesResponseType(typeof(bool), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(bool), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType(typeof(bool), (int)HttpStatusCode.InternalServerError)]
public async Task<ActionResult<AccessTokenResponse>> GenerateAccessToken()
{
var client = new HttpClient();
MultipartFormDataContent clientData = new MultipartFormDataContent
{
{ new StringContent("[Removed]"), "client_id" },
{ new StringContent("[Removed]"), "client_secret" },
{ new StringContent("client_credentials"), "grant_type" },
};
try
{
var responseObject = new AccessTokenResponse();
var response = await client.PostAsync(AccessTokenEndpoint, clientData);
var responseString = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
responseString = await response.Content.ReadAsStringAsync();
responseObject = JsonConvert.DeserializeObject<AccessTokenResponse>(responseString);
return Ok(responseObject);
}
return StatusCode(400, responseObject);
}
catch (Exception ex)
{
Logger.Log(ex);
return StatusCode(500, false);
}
}
The response from the C# code is:
{"error":"unsupported_grant_type","error_description":"Use \"authorization_code\" or \"refresh_token\" or \"client_credentials\" or \"urn:ietf:params:oauth:grant-type:jwt-bearer\" as the grant_type.","error_uri":"https://developer.salesforce.com/docs"}
I am very confused as to what I am missing. I clearly have the grant_type provided. However not matter what I set grant_type to I get the same error message listed above. I suspected it might be something to do with the content-type. On the valid request in Postman I clicked code -> then cURL and it gave me this:
curl -X POST \
https://[removed].auth.marketingcloudapis.com/v2/token \
-H 'Content-Type: application/json' \
-H 'Postman-Token: f469a34a-194e-44b4-82aa-c5d46a1528f7' \
-H 'cache-control: no-cache' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F client_id=[removed] \
-F client_secret=[removed] \
-F grant_type=client_credentials
I tried adding the missing headers to my request by doing this (just above the try block):
clientData.Headers.TryAddWithoutValidation("Content-Type", "application/json");
clientData.Headers.TryAddWithoutValidation("Content-type", "multipart/form-data");
//clientData.Headers.TryAddWithoutValidation("Content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
But then I was met with error 500 responses (if I have application/json and multipart/form-data) and Unsupported Media Type if I just have application/json
I am completely stumped here. Any ideas what I am doing wrong?
I am trying to access the Snipcart API (Reference - https://docs.snipcart.com/api-reference/authentication). I have created an API key and followed the steps mentioned in the documentation.
I am trying to Convert a CURL request to C#. I chose to use HttpWebRequest. I get 401 Unauthorized returned from the Server. I am not able to figure out what's wrong with my request.
Actual Curl Request: - curl -H "Accept: application/json"
https://app.snipcart.com/api/orders
-u {API_KEY}:
The following is the code that i tried converting the above curl request to
string baseURL = "https://app.snipcart.com/api/orders";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseURL);
req.AllowAutoRedirect = true;
req.ContentType = "application/json";
req.Accept = "application/json";
req.Method = "GET";
req.Headers.Add("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
string jsonResponse = null;
using (WebResponse resp = req.GetResponse())
{
if (req.HaveResponse && resp != null)
{
using (var reader = new StreamReader(resp.GetResponseStream()))
{
jsonResponse = reader.ReadToEnd();
}
}
}
Console.Write(jsonResponse);
You need to send the header as a basic auth header instead of "API_Key" Try something like this.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseURL);
req.AllowAutoRedirect = true;
req.ContentType = "application/json";
req.Accept = "application/json";
req.Method = "GET";
var basicAuthHeader = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("MY_API_KEY_VALUE_COMES_HERE"));
req.Headers.Add("Authorization", "Basic " + basicAuthHeader);
The API reference from Snipcart says you need Basic HTTP Authentication.
When I have a look at your code, I think you should change this line
req.Headers.Add("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
to
req.Credentials = new NetworkCredential("API_Key", "MY_API_KEY_VALUE_COMES_HERE");
A kind of the same issue is described in this topic, you can take it as reference.
If it's not solving the issue, you could have a closer look at the curl API parameters manual, and then translate it to C# code.
curl -H "Accept: application/json" \
https://app.snipcart.com/api/orders \
-u {API_KEY}:
I am getting a 400 bad request error when trying to connect to the Urban Airship Rest API. Below is the curl command I am trying to replicate in .NET. The .NET code is at the end. Please help.
curl -v -X POST
-u "username:passowrd"
-H "Content-type: application/json"
-H "Accept: application/vnd.urbanairship+json; version=3;"
--data '{"audience" : {"tag":"1_13_98"},
"device_types" : "all",
"notification" : {"alert": "Tag push alert"}
}'
https://go.urbanairship.com/api/push
The c# code I am trying to use is:
var json = gcm.ToJsonString();
Console.WriteLine("JSON GCM Message: " + json);
var uri = new Uri("https://go.urbanairship.com/api/push/?");
var encoding = new UTF8Encoding();
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Credentials = new NetworkCredential(username, master);
request.ContentType = "application/json";
WebHeaderCollection myWebHeaderCollection = request.Headers;
myWebHeaderCollection.Add(HttpRequestHeader.Accept, "application/vnd.urbanairship+json; version=3;");
request.ContentLength = encoding.GetByteCount(json);
using (var stream = request.GetRequestStream())
{
stream.Write(encoding.GetBytes(json), 0, encoding.GetByteCount(json));
stream.Close();
var response = request.GetResponse();
response.Close();
}
return true;
The API for urbanAirship can be found here:
http://docs.urbanairship.com/reference/api/v3/push.html
And here is an example request..
POST /api/push HTTP/1.1
Authorization: Basic <master authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;
{
"audience" : {
"device_token" : "998BAD77A8347EFE7920F5367A4811C4385D526AE42C598A629A73B94EEDBAC8"
},
"notification" : {
"alert" : "Hello!"
},
"device_types" : "all"
}
I've created a c# .Net library for talking to Urban Airship API V3
You can find it here:
https://github.com/JeffGos/urbanairsharp
Hope it helps
Instead of using the header collection (which is throwing an exception) try setting the Accept property on the Request object, e.g. request.Accept = "application/vnd.urbanairship+json; version=3;"
If you still get a 400, try looking in the response body for more details.
I'm trying to Make your first call Paypal where the post message are in curl. I want to convert them to C#. But I can't edit Accept header.
curl https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" \
-d "grant_type=client_credentials"
My code is
string url = "https://api.sandbox.paypal.com/v1/oauth2/token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
//request.ContentType = "Content-type: text/xml";
//Client.Headers.Add(HttpRequestHeader.UserAgent, "user agent to send");
//request.Headers.Add(HttpRequestHeader.Accept, "application/json");
//request.Headers.Add(HttpRequestHeader.Referer, "string");
//request.Headers.Add(HttpRequestHeader.AcceptLanguage, "string");
request.Method = "POST";
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo));
//request.Headers["Accept"] = "application/json";
request.Headers["Accept-Language"] = "en_US";
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("grant_type=client_credentials");
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
I'm getting internal server error 500. But it works fine with curl. How can I do this in C#?
One method I have used before to supply named values like this is to use the UploadValues method of a WebClient. This perfectly replicates the functionality you find in curl (I have used this for integration with the Instagram API for the same purpose).
Here is a little sample code to illustrate:
string authInfo = "AfKNLhCngYfGb-Eyv5gn0MnzCDBHD7T9OD7PATaJWQzP3I1xDRV1mMK1i3WO:ECSAgxAiBE00pq-SY9YB5tHw0fd2UlayHGfMr5fjAaULMD2NFP1syLY7GCzt";
WebClient client = new WebClient();
NameValueCollection values;
values = new NameValueCollection();
values.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(authInfo)));
values.Add("Accept", "application/json");
values.Add("Accept-Language", "en_US");
client.UploadValues("https://api.sandbox.paypal.com/v1/oauth2/token", values);
This may not work out of the box (as I have laid it out above) but will hopefully take you in the right direction.