i've been following this Making a cURL call in C# for trying to make a request with the LiveChat API in curl and receive the result on my C# application,
the request should be filled as the following as explained in: http://developers.livechatinc.com/rest-api/#!introduction
curl "https://api.livechatinc.com/agents" \
-u john.doe#mycompany.com:c14b85863755158d7aa5cc4ba17f61cb \
-H X-API-Version:2
This is what i did in C#:
static void Main(string[] args)
{
RequestTest();
Console.ReadKey();
}
private static async void RequestTest()
{
var client = new HttpClient();
// Create the HttpContent for the form to be posted.
var requestContent = new FormUrlEncodedContent(new[] {new KeyValuePair<string, string>("myemail:myapikey", "X-API-Version:2"),});
// Get the response.
HttpResponseMessage response = await client.PostAsync(
"https://api.livechatinc.com/agents",
requestContent);
// Get the response content.
HttpContent responseContent = response.Content;
// Get the stream of the content.
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
// Write the output.
Console.WriteLine(await reader.ReadToEndAsync());
}
}
The result seems to be allways the same "Cannot POST to /agents"
You're performing a POST operation here. That is reserved for creating a new agent and requires that you send in a JSON request payload. See here:
developers.livechatinc.com/rest-api/#create-agent
What you want to do is a GET operation:
developers.livechatinc.com/rest-api/#get-single-agent
Instead of using PostAsync you'll need to create an HttpRequestMessage, set the Method to GET, set your headers and then use SendAsync. See solution here: Adding Http Headers to HttpClient
Remember, for REST API:
POST = Create Operations,
GET = Read Operations,
PUT = Update Operations,
DELETE = Delete Operations
Related
I don't understand the variable types and how i can utilize client to retrieve the http Status code.
The client variable is a standard HttpClient object.
The attached picture is the function I'm trying to retrieve the status code during. Any help would be greatly appreciated.
[1]: https://i.stack.imgur.com/9iR3g.png
It should be easy as
var client = new HttpClient();
var results = await client.GetAsync("https://stackoverflow.com");
Console.WriteLine(results.StatusCode);
Your issue is that you're not getting response object. You are getting the content of the body of the response.
Here is a sample code:
void SimpleApiCall()
{
Uri endpoint = new Uri("https://www.7timer.info/bin/");
using var client = new HttpClient();
client.BaseAddress = endpoint;
// Get the response only here, and then get the content
// I'm using GetAwaiter().GetResult() because client.GetAsync() returns a Task and you're not using the async await since this is a button click event
var response = client.GetAsync("astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0").GetAwaiter().GetResult();
// Status code will be available in the response
Console.WriteLine($"Status code: {response.StatusCode}");
// For the Reason phrase, it will be Ok for 200, Not Found for a 404 response...
Console.WriteLine($"Reason Phrase: {response.ReasonPhrase}");
// read the content of the response without the await keyword, use the .GetAwaiter().GetResult()
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Console.WriteLine("Content:");
Console.WriteLine(content);
}
Same goes for PostAsync and all the other operations...
I have create gandi api code for create domain and for that i have write below code, but it show me 400 bad request error
public async System.Threading.Tasks.Task<JsonResult> InsertDomain(DomainDetails domainDetails)
{
HttpResponseMessage response = new HttpResponseMessage();
try
{
var url = "https://api.gandi.net/v5/domain/domains";
using ( var client = new HttpClient() )
{
var json = new JavaScriptSerializer().Serialize(domainDetails);
HttpContent HttpContent = new StringContent(json, Encoding.UTF8, "application/json");
var MyHttpClient = new HttpClient();
MyHttpClient.DefaultRequestHeaders.Add("authorization", GANDI_API_Key);
response = await MyHttpClient.PostAsync(url, HttpContent);
}
}
catch ( Exception ex )
{
throw;
}
return Json(new { result = response }, JsonRequestBehavior.AllowGet);
}
but when i try to pass same data using postman then it's working fine below code is my postman data
Body
{
"fqdn":"dedasdom1906.com",
"owner":
{
"city":"Paris",
"given":"Alice",
"family":"Doe",
"zip":"75001",
"country":"FR",
"streetaddr":"5 rue neuve",
"phone":"+33.123456789",
"state":"FR-J",
"type":"0",
"email":"alice#example.org"
}
}
Header
authorization : Apikey
Content-Type : application/json
I havent worked with this endpoint, but you are missing the return type.
the next thing i would try is to paste json string directly in the StringContent.
please paste the correct string content(rename the variable)
if none of this help you, please give more details.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
For the https://api.gandi.net/v5/domain/domains endpoint, use HTTP GET (HttpClient.GetAsync) to retrieve a list of your domains. Use HTTP POST (HttpClient.PostAsync) to create a new domain.
If you're trying to POST JSON, I would use the PostAsJsonAsync method, example here:
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync(
"api/products", product);
...
Also note your auth header needs to start with "apikey" though it looks like you have that working. Curl example:
curl -X GET \
https://api.gandi.net/v5/domain/domains \
-H 'authorization: Apikey your-api-key'
https://api.gandi.net/docs/domains/
I am trying to send a POST request from my ASP.NET Core Web API Project but the request is never sent. The method gets executed with no errors but the request never gets sent out from the async method.
My Implementation:
public async void notify(String message)
{
String url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("application/x-www-form-urlencoded;charset=UTF-8",
Encoding.UTF8, "application/json");
Byte[] byteArray = Encoding.UTF8.GetBytes("{\"text\":\"" + message + "\"}");
request.Content.Headers.ContentLength = byteArray.Length;
await client.SendAsync(request).ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
});
}
Is this the proper way of making a POST request from a Core Web API project? Thank you in advance
First of all, there is a dedicated method PostAsync in the HttpClient class ( or even PostAsJsonAsync extension) which you can use to send POST requests without creating HttpRequstMessage manually.
Now about your code - I believe you want to post following JSON string:
{"text":"someMessage"}
You should set this string as a content of StringContent which you are sending:
var json = "{\"text\":\"" + message + "\"}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
Currently you are trying to post mediatype string as a value to your API endpoint. Of course it cannot be deserialized into your model.
Note1: StringContent will automatically add Content-Length header with the appropriate value. You should not do that manually.
Note2: Unless this is an event handler, you should not use async void - use async Task instead.
Same task with PostAsJsonAsync usage will look like:
public async Task Notify(string message)
{
var string url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
var notification = new Notification { Text = message }; // use some model class
var resonse = await client.PostAsJsonAsync("relativeAddress", notification);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
}
}
In this case, your model will be automatically serialized into JSON, appropriate content will be created and POST request will be sent.
Try Adding [IgnoreAntiforgeryToken] on top of the Post Action like this
I am trying to send a HTTP post request to microsoft Bing speech API o transcribe an audio file. First we need to send a post request to get an "access token" as a response, then this token is used (as authorisation" in another post request to upload the actual file and get the transcription in the response. I can send the first post request and successfully get the access token, but I am not able to get a reasonable response for my second post request. I follow this page: https://www.microsoft.com/cognitive-services/en-us/speech-api/documentation/api-reference-rest/bingvoicerecognition
This is the second post request:
Guid requestId = Guid.NewGuid();
var Uri = #"https://speech.platform.bing.com/recognize?version=3.0&requestid=" + requestId.ToString() + #"&appID=D4D52672-91D7-4C74-8AD8-42B1D981415A&format=json&locale=en-US&device.os=Windows%20OS&scenarios=ulm&instanceid=f1efbd27-25fd-4212-9332-77cd63176112";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Uri);
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
request.Headers.TryAddWithoutValidation("Content-Type", #"audio/wav; samplerate=16000");
MemoryStream ms = new MemoryStream();
using (var fs = System.IO.File.OpenRead("audio.wav"))
{
byte[] buffer = new byte[1024 * 8];
while (fs.Read(buffer, 0, buffer.Length) > 0)
{
ms.Write(buffer, 0, buffer.Length);
}
fs.Close();
}
ms.Seek(0, SeekOrigin.Begin);
HttpContent _Body = new StreamContent(ms);
request.Content = _Body;
var client2 = new HttpClient();
var response2 = client2.SendAsync(request);
I guess the problem is where I set the "Content-Type" for the header. The reason is when I debug, I don't see this property being set in the Header of the request. In fact, there is no Content-Type in the header. Any help would be appreciated. This page, which talks about the equivalent curl command, can also be helpful: https://social.msdn.microsoft.com/Forums/en-US/ad73e4f1-e576-4080-9fe7-060cc2f583ca/microsoft-bing-voice-recognition-api-authorization-404resource-not-found?forum=SpeechService
Content-Type is a content related header. The following code works for me:
public async Task<string> SendRequestAsync(string url, string bearerToken, string contentType, string fileName)
{
var content = new StreamContent(File.OpenRead(fileName));
content.Headers.TryAddWithoutValidation("Content-Type", contentType);
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
var response = await httpClient.PostAsync(url, content);
return await response.Content.ReadAsStringAsync();
}
}
The invocation in your case (if you work in synchronous context):
var result = SendRequestAsync(Uri, accessToken, "audio/wav; samplerate=16000", "audio.wav").Result;
You can send the following header instead, to not have to do 2 requests because of the token.
If you want to not have to login each time instead of using the 'Authorization': 'Bearer {TOKEN}' header you could use the 'Ocp-Apim-Subscription-Key': '{YOUR AZURE TOKEN}' in order to not have to make a authorisation factory or more requests than necessary to the application and make it faster
NOTE: {TOKEN} is a JWT token like
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzY29wZSI6Imh0dHBzOi8vc3BlZWNoLnBsYXRmb3JtLmJpbmcuY29tIiwic3Vic2NyaXB0aW9uLWlkIjoiZmFhZTNlYTkxNmI1NGMxZWEyODY4MDlhYTg3ZWE1MmUiLCJwcm9kdWN0LWlkIjoiQmluZy5TcGVlY2guUHJldmlldyIsImNvZ25pdGl2ZS1zZXJ2aWNlcy1lbmRwb2ludCI6Imh0dHBzOi8vYXBpLmNvZ25pdGl2ZS5taWNyb3NvZnQuY29tL2ludGVybmFsL3YxLjAvIiwiYXp1cmUtcmVzb3VyY2UtaWQiOiIiLCJpc3MiOiJ1cm46bXMuY29nbml0aXZlc2VydmljZXMiLCJhdWQiOiJ1cm46bXMuc3BlZWNoIiwiZXhwIjoxNTAwODgxNjIzfQ.KdlCrIJ_H0jxs1yyeyYxYR7ucbLuFKT__ep7lGJmGbU
NOTE2: {YOUR AZURE TOKEN} is like d5kals90935b40809dc6k38533c21e85 and you find it here
The request would look like this:
curl -v -X POST "https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=es-ES&locale=es-ES&format=simple&requestid=req_id" -H "Ocp-Apim-Subscription-Key: d5kals90935b40809dc6k38533c21e85" -H 'Transfer-Encoding: chunked' -H 'Content-type: audio/wav; codec="audio/pcm"; samplerate=8000' --data-binary #"{BINAYFILE}.wav"
I'm trying to call this API from my C# app:
https://ocr.space/OCRAPI
When I call it from curl, it just works fine:
curl -k --form "file=#filename.jpg" --form "apikey=helloworld" --form "language=eng" https://api.ocr.space/Parse/Image
I implemented it this way:
[TestMethod]
public async Task Test_Curl_Call()
{
var client = new HttpClient();
String cur_dir = Directory.GetCurrentDirectory();
// Create the HttpContent for the form to be posted.
var requestContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>( "file", "#filename.jpg"), //I also tried "filename.jpg"
new KeyValuePair<string, string>( "apikey", "helloworld" ),
new KeyValuePair<string, string>( "language", "eng")});
// Get the response.
HttpResponseMessage response = await client.PostAsync(
"https://api.ocr.space/Parse/Image",
requestContent);
// Get the response content.
HttpContent responseContent = response.Content;
// Get the stream of the content.
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
// Write the output.
String result = await reader.ReadToEndAsync();
Console.WriteLine(result);
}
}
I get this answer :
{
"ParsedResults":null,
"OCRExitCode":99,
"IsErroredOnProcessing":true,
"ErrorMessage":"No file uploaded or URL provided",
"ErrorDetails":"",
"ProcessingTimeInMilliseconds":"0"
}
Any clue?
What's the # character for in "file=#filename.jpg"?
I put my filename.jpg file in the project and test project bin/debug directory and run my test project in debug mode.
So I don't think the error points to the file not being where expected.
I'd rather suspect a syntax error in my code.
The error message is telling you what's wrong:
No file uploaded or URL provided
You sent a filename to the service in your code, but that's not the same thing as giving curl a filename. curl is smart enough to read the file and upload the contents with your request, but in your C# code, you'll have to do that yourself. The steps will be:
Read the file bytes from disk.
Create a multipart request with two parts: the API key ("helloworld"), and the file bytes.
POST this request to the API.
Fortunately, it's pretty easy. This question demonstrates the syntax to set up a multipart request.
This code worked for me:
public async Task<string> TestOcrAsync(string filePath)
{
// Read the file bytes
var fileBytes = File.ReadAllBytes(filePath);
var fileName = Path.GetFileName(filePath);
// Set up the multipart request
var requestContent = new MultipartFormDataContent();
// Add the demo API key ("helloworld")
requestContent.Add(new StringContent("helloworld"), "apikey");
// Add the file content
var imageContent = new ByteArrayContent(fileBytes);
imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
requestContent.Add(imageContent, "file", fileName);
// POST to the API
var client = new HttpClient();
var response = await client.PostAsync("https://api.ocr.space/parse/image", requestContent);
return await response.Content.ReadAsStringAsync();
}