I was trying to write a post API call to watson tone analyzer service in C#. It seems that the way to authenticate a user was changed lately from username and password to an api key.
I was trying to pass the apikey through "Authorization" header, or through a header called "apikey".. In both cases I received error 401 Unauthorized.. The other header I was using is Content-Type sets to application/json..
This calls doesn't work in a .net project nor in postman.
How can I send an API request using C#, how shell I pass the api key, and what headers should I use ?
This is the code I tried(This code returns an error of internal server error 500, while the tests I did with postman returns 401 Unauthorized):
HttpClient client = new HttpClient();
string baseURL;
string apikey= "****************";
baseURL = "https://gateway-lon.watsonplatform.net/tone-analyzer/api/v3/tone?version=2017-09-21";
string postData = "{\"text\": \"" + "hi hello" + "\"}";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("apikey", apikey);
var response = client.PostAsync(baseURL, new StringContent(postData, Encoding.UTF8, "application/json")).Result;
Console.WriteLine(response);
The error I am receiving:
StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Mime-Version: 1.0
Connection: close
Date: Sun, 17 Feb 2019 11:37:53 GMT
Server: AkamaiGHost
Content-Length: 177
Content-Type: text/html
Expires: Sun, 17 Feb 2019 11:37:53 GMT
}
For this to work you need to do a proper basic authorization (see Authorization section at https://cloud.ibm.com/apidocs/tone-analyzer ). According to RFC 7617 basic authorization means the authorization scheme is Basic
and the authorization parameter is username:password in Base64 encoding.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes("apikey:" + apikey)));
The following code worked for me:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes("apikey:" + apikey)));
string postData = "{\"text\": \"" + "I am happy it finally worked" + "\"}";
var response = client.PostAsync("https://gateway-lon.watsonplatform.net/tone-analyzer/api/v3/tone?version=2017-09-21", new StringContent(postData, Encoding.UTF8, "application/json")).Result;
var responseContent = response.Content.ReadAsStringAsync().Result;
Which returned {"document_tone":{"tones":[{"score":0.956143,"tone_id":"joy","tone_name":"Joy"},{"score":0.620279,"tone_id":"analytical","tone_name":"Analytical"}]}}
.
As a side note, I initially used the Frankfurt gateway ( gateway-fra ) and when I used my apikey for this gateway on the London gateway ( gateway-lon ) I also received server error 500 (Internal server error). For other gateways I received error 401 (Unauthorized), because the apikeys seem to be per service and gateway/location. After I deleted my ToneAnalyzer service and set up an new one this time for the London gateway, it worked. So I guess, IBM's authorization server or the Akamai load balancer they are using is a little bit wonky when you use an apikey for one gateway on another gateway.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.