converting cURL request to asp.net c# - c#

i try to work around converting this to c# but i cant understand the tags like -H others am familiar with like the BVN and secret key are clear to me, but i'm literally at cross road.
curl https://api.paystack.co/bank/resolve_bvn/:BVN
-H "Authorization: Bearer YOUR_SECRET_KEY"
-X GET
this enlightened me but i'm new to using curl

I only want to explain command flags.
-H means request header. In your case, you need to set header with name Authorization to the secret key Bearer YOUR_SECRET_KEY eg Bearer abcd123566 where abcd123566 is your secret key.
-X GET means your request method (HTTP verb) should be GET

-H means the headers of the request. In C# the code would look something like this:
private static HttpClient httpClient = new HttpClient();
var uri = new Uri("https://api.paystack.co/bank/resolve_bvn/:BVN");
var reqMessage = new HttpRequestMessage(HttpMethod.Get, uri);
reqMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "YOUR_SECRET_KEY")
// Setting the request content (including content-type)
reqMessage.Content = new StringContent("Content of request", Encoding.UTF8, "application/json");
var resp = await httpClient.SendAsync(reqMessage);
You can read more HttpClient and API requests in C# here:
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.1
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

Related

Receiving 401 "Unauthorized" error while using Google Cloud AutoML via HttpClient

I am writing a WPF application with C# that attempts to make an Google Cloud AutoML API call with HttpClient. I am able to make contact with the server but always get back an "Unauthorized" response. I have scoured StackOverflow and the AutoML documentation for any hint as to how to properly turn the "CURL" request into a simple HTTP request that I can execute programmatically within my C# application, but haven't found anything that gave enough guidance up to this point (hence my question).
Here is the CURL request that I am modeling my HTTP request after:
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
https://automl.googleapis.com/v1beta1/projects/image-object-detection/locations/us-central1/models/MyProjectId:predict -d #request.json
There are elements of this request that I cannot figure out how to translate into C#, namely the Authorization: Bearer component. Do I need to somehow find a token and add it to a header or something? If so, how do I acquire this token in string form? That seems to be what I'm really stuck on.
And here is the C# code that I actually have up to this point.
public async Task<object> GetPrediction(string imagePath)
{
string apiKey = "MyApiKey";
string projectId = "MyProjectId";
HttpResponseMessage response;
byte[] img = File.ReadAllBytes(imagePath);
string jsonBody = "{\"payload\":{\"image\":{\"imageBytes\":\"" + Encoding.UTF8.GetString(imgBody) + "\"}}}";
string uri = $"https://automl.googleapis.com/v1beta1/projects/image-object-detection/locations/us-central1/models/{projectId}:predict?key={apiKey}";
string token = “MyToken”;
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, uri);
request.Headers.TryAddWithoutValidation("Content-Type", "application/json");
request.Headers.Authorization = new AuthenticarionHeaderValue(“Bearer”, token);
request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
response = await client.SendAsync(request);
return Task.FromResult(response);
}
This code basically makes contact, then I get back a 401 "unauthorized" status code. Any suggestions or guidance would be greatly appreciated, and if additional information is required, I would be glad to post more. Thanks!
Update:
I modified the code block to include the suggested change from Nkosi, but I am still seeing the same 401 status code.
I am not seeing the Authorization header added to request
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)"
like in the cURL example
set the Authorization on the request before sending it
//...
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "{token-here}");
//...

Posting Json string to web api c#

I'm quite new to handling json data and web apis but I'm currently creating an application to further my knowledge on them.
At the moment I can do get requests and these work fine however I'm having issues with posts. I'm trying to post json data to Jira Confluence to create a new page.
On https://developer.atlassian.com/confdev/confluence-server-rest-api/confluence-rest-api-examples it gives the below code to make a curl request
curl -u admin:admin -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page",
"ancestors":[{"id":456}], "space":{"key":"TST"},"body":{"storage":{"value":
"<p>This is a new page</p>","representation":"storage"}}}'
http://localhost:8080/confluence/rest/api/content/ | python -mjson.tool
I am currently using the below code and it comes back with a status 200 but I don't see the created page on confluence. I was wondering if anyone could help me out
HttpClient _webRequest = new HttpClient();
byte[] cred = UTF8Encoding.UTF8.GetBytes(credentials);
_webRequest.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
_webRequest.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
string response = "{\"type\":\"page\",\"title\":\"new page\",\"ancestors\":[{\"id\":40635756}],\"space\":{\"key\":\"VG\"},\"body\":{\"storage\":{\"value\":\"<p>This is a new page</p>\",\"representation\":\"storage\"}}}"
var content = new StringContent(lol, Encoding.UTF8, "application/json");
var result = _webRequest.PostAsync("http://jirasite/confluence/rest/api/content/", content).Result;
Your auth header looks incorrect... You are missing the whitespace after "Basic" it should be like this "Basic xxx".
Please take a look at the following document:
https://developer.atlassian.com/confdev/confluence-server-rest-api/confluence-rest-api-examples?_ga=2.72183699.1804458933.1496916716-1816616270.1496916716#ConfluenceRESTAPIExamples-Createanewpage
Regards
Craig

c# - curl equivalent for multipart form data post request

I'm making a call to third-party api. Here's the third-party api info and what they expect:
POST /api/ HTTP/1.1
Host: testurl.com
Content-Type: multipart/form-data
curl https://testurl.com/api \
-H "Content-Type: multipart/form-data" \
-F "document[description]=meeting notes" \
-F "document[matter][id]=123" \
-F "document[document_category][name]=Offers" \
-F "document_version[last_modified_at]=2013-12-03T23:35:32+00:00" \
-F "document_version[uploaded_data]=#test.txt"
I need to write a c# equivalent post method to send these info. I have taken care of the header in the curl call, but I'm not sure on the rest of the form-data. For instance, the "document" and "document_version" along with their respective attributes (or whatever they are), how do I pass those info along?
Here's what I found: http://www.briangrinstead.com/blog/multipart-form-post-in-c
I did exactly what's done in that link, but got back Bad Request error. More specific error:
{"error":"api error","message":"undefined method `key?' for nil:NilClass"}
I have no idea what's going on in the third-api so I don't know what this error means. Also, I'm trying to post pdf doc.
You can use the HttpClient
var client = new HttpClient();
var image = File.ReadAllBytes("c:\\test.png");
var formData = new MultipartFormDataContent();
formData.Add(new StreamContent(new MemoryStream(image)), "name","fileName.png");
formData.Add(new StringContent("content"), "name");
var response = client.PostAsync("http://localhost:5001/api/someMethod", formData).Result;
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Console.WriteLine(content);
}
This works good for me.

cURL and .Net (c#) API Token

I've read and re-read stackoverflow and google searches in general and I just can't seem to find a solution to my issue. I'm positive it is my ignorance.
I am trying to reproduce a cUrl call in .Net (c# specifically) and am having a devil of a time wading through and figuring out why it isn't working. this cUrl call uses a token and the username is not required when I do so.
The following cUrl call works as expected when called from the command line. The API token has been changed to protect the innocent.
curl -u x:8cb60a319c71be3356da2ea6d7c7650b -H "Content-Type: application/json" https://deskapi.gotoassist.com/v1/incidents.json
I have tried the following:
WebRequestHandler webHandler = new WebRequestHandler();
webHandler.Credentials = new System.Net.NetworkCredential("x", "8cb60a319c71be3356da2ea6d7c7650b");
HttpClient client = new HttpClient(webHandler);
client.BaseAddress = new Uri("https://deskapi.gotoassist.com/v1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("incidents.json");
if (response.IsSuccessStatusCode)
{
Console.Write("Success!");
}
The response gives a "Bad Request". The actual requestmessage is:
response.RequestMessage {Method: GET, RequestUri: 'https://deskapi.gotoassist.com/v1/incidents.json', Version: 1.1, Content: , Headers:
{
Accept: application/json
}}
If that helps any.
Based on other stackoverflow examples I also tried:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://deskapi.gotoassist.com/v1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("8cb60a319c71be3356da2ea6d7c7650b");
HttpResponseMessage response = await client.GetAsync("incidents.json");
if (response.IsSuccessStatusCode)
{
Console.Write("Success!");
}
Console.Write(response.RequestMessage.ToString());
With another "Bad Request". The message is similar:
response.RequestMessage {Method: GET, RequestUri: 'https://deskapi.gotoassist.com/v1/incidents.json', Version: 1.1, Content: , Headers:
{
Accept: application/json
Authorization: 8cb60a319c71be3356da2ea6d7c7650b
}} System.Net.Http.HttpRequestMessage
The actual uri looks correct to me. The content type looks correct to me. The only thing I can't find a definitive example to do is send that "x:8cb60a319c71be3356da2ea6d7c7650b" other than the ways I have tried it.
Any thoughts? This is my first time trying to do anything like this so hopefully I'm just doing some ignorant something-something. I've tried to follow example after example but nothing gets me an successful call. Thank you in advance for helping.
The cUrl command uses the Content-Type header which is only intended for when you are sending a body e.g. with PUT or POST. It is not the same header as Accept. Accept is the correct header to send with a GET request.
When I try hitting the server without any auth header, I get back a 400 with the message "Unknown OAuth signature method". The response for missing auth should really be a 401 and a www-authenticate header that tells us what kind of scheme to use.
Assuming that the server is actually looking for a OAuth2 bearer token, then you might want to try,
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer","8cb60a319c71be3356da2ea6d7c7650b");
Debug your code using Fiddler
By using Fiddler you will exactly know what is happenning during these calls,
Run it against CURL command line
Run it against your code
Basically you have nothing to do, just install it, run it and do some Internet activity. You will then see what's being intercepted.
To fix your problem, look at the Inspectors/Raw tab and compare them.
Here's an example of an issue I've had and what I found out that was missing with Fiddler :
Equivalent of "curl -F" parameter for System.Net.Http.MultipartFormDataContent?

Rackspace cloud files REST api inexplicably getting bad request response

I am trying to write a program to authenticate to rackspace cloud files. The following command works with curl just fine:
curl -k -X POST https://identity.api.rackspacecloud.com/v2.0/tokens -d '{ "auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"myusername","apiKey":"mykey"}}}' -H "Content-type: application/json"
However, I get a bad request (400) error with the following code:
var client = new RestClient("https://identity.api.rackspacecloud.com/v2.0");
var request = new RestRequest("tokens", Method.POST);
request.RequestFormat = DataFormat.Json;
string serText = "{ \"auth\":{\"RAX-KSKEY:apiKeyCredentials\"{\"username\":\"myusername\",\"apiKey\":\"mykey\"}}}";
request.AddBody(serText);
RestResponse response = (RestResponse)client.Execute(request);
Anybody have any ideas?
So, when adding my json body I need to do so as follows:
request.AddParameter("application/json", serText, ParameterType.RequestBody);
So basically, it was trying to serialize my already serialized json. I found this out by finding some other questions on stack overflow. I would point out this is not explained at all the official "documentation" for RestSharp.

Categories