0

I am trying to access the JSON response that the following code should generate:

public static async Task<string> GetResponseString(string refreshToken) { var client = new HttpClient(); client.BaseAddress = new Uri("https://www.strava.com"); var request = new HttpRequestMessage(HttpMethod.Post, "/oauth/token"); var keyValues = new List<KeyValuePair<string, string>>(); keyValues.Add(new KeyValuePair<string, string>("client_id", "some_id")); keyValues.Add(new KeyValuePair<string, string>("client_secret", "some_secret")); keyValues.Add(new KeyValuePair<string, string>("refresh_token", refreshToken)); keyValues.Add(new KeyValuePair<string, string>("grant_type", "refresh_token")); request.Content = new FormUrlEncodedContent(keyValues); var response = await client.SendAsync(request); var result = await response.Content.ReadAsStringAsync(); return result; } 

The expected result looks like this.

 { "token_type": "Bearer", "access_token": "a9b723...", "expires_at":1568775134, "expires_in":20566, "refresh_token":"b5c569..." } 

When doing this in Postman or Javscript the result is correct, so I guess I am not capable of accessing the task string in a correct manner :-)

Any help pointing me in the right direction will be much appreciated.

Thnx

6
  • 4
    You show your code which looks ok but you don't show how you are consuming this code. If it's returning a task and you aren't awaiting the result then you need to do so. The result property of the task will contain the JSON. Commented Jul 11, 2020 at 15:58
  • @Charleh I am calling it using var result = collection.GetResponseString("some_token"); Commented Jul 11, 2020 at 16:00
  • 1
    Right so you need to await the result, the task is async, it runs asynchronously so execution will continue unless you await the result. You can call GetAwaiter().GetResult() to block the current thread until the async task completes and return the result of the task. GetResponseString().GetAwaiter().GetResult(), though you might also want to check if the result was successful etc. Commented Jul 11, 2020 at 16:04
  • Bear in mind, it's much better to await the result due to potential deadlocks, stackoverflow.com/questions/17284517/… though in your case you might be ok, it depends on what's calling the method. Commented Jul 11, 2020 at 16:07
  • Thanks you @Charleh The request just times out now however. I was under the impression that I was already waiting for the result using var result = await response.Content.ReadAsStringAsync(); So the .GetAwaiter().GetResult() should not be necessary ? Commented Jul 11, 2020 at 17:45

2 Answers 2

1

The code contains more than one mistake.

Try avoiding var keyword if you're not absolutely sure what are you doing. var can hide original problem and the question is example how var kills the time. I recommend using explicit types where possible.

As maintained above in comments you unwrapping string result is required from awaitable Task with await.

private static readonly HttpClient client = new HttpClient(); private static async Task<string> GetResponseStringAsync(string url, Dictionary<string, string> formData) { using (HttpContent content = new FormUrlEncodedContent(formData)) using (HttpResponseMessage response = await client.PostAsync(url, content)) { response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } } 

Usage

Dictionary<string, string> postData = new Dictionary<string, string>(); postData.Add("client_id", "some_id"); postData.Add("client_secret", "some_secret"); postData.Add("refresh_token", refreshToken); postData.Add("grant_type", "refresh_token"); try { string result = await GetResponseStringAsync("https://www.strava.com/oauth/token", postData); // success here } catch (Exception ex) { Debug.WriteLine(ex.Message); // request failed } 

Asynchronous programming

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for the code suggestion. I have read the doc about HttpClient, I am however not a native C# programmer, but fluent in front end development. This is just a hobby project for myself. The return await response.ReadAsStringAsync(); should be return await response.Content.ReadAsStringAsync(); Right?
The string result = await GetResponseStringAsync("https://www.strava.com/oauth/token", postData); fails as await can only be used within a async method?
@iAyAy 1) fixed, exactly, thanks! 2) yes, the caller method must be async
@iAyAy what kind of app? Can you show the caller method? Maybe i can help.
-1

I'm assuming that the consuming code is saying Console.WriteLine(GetResponseString("someToken"))

The reason it's not printing out correctly, is because the GetResponseString() is returning a Task<string>, not a string. This is because ReadAsStringAsync() returns a Task<string>.

To print the json that you expect, you need to write... Console.WriteLine(GetResponseString("someToken").Result

Alternatively, you can switch your method to just return a string instead of a Task<string>, and modify the method as such... return await response.Content.ReadAsStringAsync().Result;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.