简体   繁体   中英

IBM Watson Tone Analyzer API call in C#

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM