I am requesting for token but code doesn't executed on SendAsync
portion. I am getting token usisng postman successfully.
Here is the example snippet:
string tokenUrl = $"https://myServiceUrl.cognitiveservices.azure.com/sts/v1.0/issuetoken";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["Content-Type"] = "application/x-www-form-urlencoded",
["Ocp-Apim-Subscription-Key"] = "MyKey"
});
HttpClient client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest); // skipped here
dynamic json = await tokenResponse.Content.ReadAsStringAsync();
var token = JsonConvert.DeserializeObject<string>(json);
I even tried without ["Content-Type"] = "application/x-www-form-urlencoded"
but doesn't work for me.
It turns out the actual cause for 'skipping' the rest of the method was accidentally not awaiting the call to GetSpeechServiceToken
in the parent method. This caused the thread execution to continue on the original thread and step out of the method, seemingly skipping the remainder.
OP fixed this by instead calling it like this: GetSpeechServiceToken().Wait()
instead of GetSpeechServiceToken()
If you run into a similar issue, below are some interesting reads by microsoft that go into more detail about asynchronous programming with async/await.
This article explain the concept in more detail, below is an excerpt
What Happens in an Async Method
The most important thing to understand in asynchronous programming is how the control flow moves from method to method. The following diagram leads you through the process.
The numbers in the diagram correspond to the following steps.
An event handler calls and awaits the
AccessTheWebAsync
async method.
AccessTheWebAsync
creates anHttpClient
instance and calls theGetStringAsync
asynchronous method to download the contents of a website as a string.Something happens in
GetStringAsync
that suspends its progress. Perhaps it must wait for a website to download or some other blocking activity. To avoid blocking resources,GetStringAsync
yields control to its caller,AccessTheWebAsync
.
GetStringAsync
returns aTask<TResult>
whereTResult
is a string, andAccessTheWebAsync
assigns the task to thegetStringTask
variable. The task represents the ongoing process for the call toGetStringAsync
, with a commitment to produce an actual string value when the work is complete.Because
getStringTask
hasn't been awaited yet,AccessTheWebAsync
can continue with other work that doesn't depend on the final result fromGetStringAsync
. That work is represented by a call to the synchronous methodDoIndependentWork
.
DoIndependentWork
is a synchronous method that does its work and returns to its caller.
AccessTheWebAsync
has run out of work that it can do without a result fromgetStringTask
.AccessTheWebAsync
next wants to calculate and return the length of the downloaded string, but the method can't calculate that value until the method has the string.Therefore,
AccessTheWebAsync
uses an await operator to suspend its progress and to yield control to the method that calledAccessTheWebAsync
.AccessTheWebAsync
returns aTask<int>
to the caller. The task represents a promise to produce an integer result that's the length of the downloaded string.Inside the caller (the event handler in this example), the processing pattern continues. The caller might do other work that doesn't depend on the result from
AccessTheWebAsync
before awaiting that result, or the caller might await immediately. The event handler is waiting forAccessTheWebAsync
, andAccessTheWebAsync
is waiting forGetStringAsync
.
GetStringAsync
completes and produces a string result. The string result isn't returned by the call toGetStringAsync
in the way that you might expect. (Remember that the method already returned a task in step 3.) Instead, the string result is stored in the task that represents the completion of the method,getStringTask
. The await operator retrieves the result fromgetStringTask
. The assignment statement assigns the retrieved result tourlContents
.When
AccessTheWebAsync
has the string result, the method can calculate the length of the string. Then the work ofAccessTheWebAsync
is also complete, and the waiting event handler can resume.
Another article published by microsoft about best practices for async/await
The reason it does't work is because your not calling the endpoint correctly:
You can use either of these endpoints:
https://api.cognitive.microsoft.com/sts/v1.0/issueToken
https://myServiceUrl.cognitiveservices.azure.com/sts/v1.0/issuetoken
And the request can be like this:
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
tokenRequest.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
var client = new HttpClient();
var tokenResponse = await client.SendAsync(tokenRequest);
var result = await tokenResponse.Content.ReadAsStringAsync();
The result is already a string with the token value. No need to deserialize it with Json.Net, that'll just cause an exception.