HttpClient 任务返回 System.Threading.Tasks.Task`1[System.String] 而不是预期的 JSON

问题描述 投票:0回答:2

我正在尝试访问以下代码应生成的 JSON 响应:

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;
    }

预期结果如下所示。

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

在 Postman 或 Javscript 中执行此操作时,结果是正确的,所以我想我无法以正确的方式访问任务字符串:-)

任何为我指明正确方向的帮助将不胜感激。

谢谢

c# async-await httpclient
2个回答
2
投票

您的代码包含多个错误。

您看到

HttpClient
文档了吗?
你知道
IDisposable
吗?
你知道
KeyValuePair
的收藏是
Dictionary
吗?

如果您不确定自己在做什么,请不要使用

var
关键字。
var
可以向您隐藏原始问题,而您的问题是
var
如何消磨您的时间。我建议尽可能使用显式类型。

是的,正如上面评论中所维护的,您必须使用

string
从可等待的
Task
中解开
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();
    }
}

使用方法

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
}

最后,是时候向异步编程问好了。 :)


0
投票

我假设使用代码是说

Console.WriteLine(GetResponseString("someToken"))

无法正确打印的原因是 GetResponseString() 返回的是

Task<string>
,而不是
string
。 这是因为 ReadAsStringAsync() 返回一个
Task<string>

要打印您期望的 json,您需要编写...

Console.WriteLine(GetResponseString("someToken").Result

或者,您可以将方法切换为仅返回

string
而不是
Task<string>
,然后修改该方法......
return await response.Content.ReadAsStringAsync().Result

© www.soinside.com 2019 - 2024. All rights reserved.