当 PostAsJsonAsync 时 unsupported_grant_type

Posted

技术标签:

【中文标题】当 PostAsJsonAsync 时 unsupported_grant_type【英文标题】:unsupported_grant_type when PostAsJsonAync 【发布时间】:2016-08-16 19:38:12 【问题描述】:

我正在尝试通过 c# 访问 ASP.NET Web API。我编写了 API,我可以使用 Postman 访问它并获得有效的响应。当出现 usernamepasswordgrant_type = password 时,API 会返回 access_token 和 refresh_token。

这是我在使用 Postman 时收到的响应的屏幕截图:

但是,当我尝试使用以下 C# 代码时:

var userToValidate = new UserToValidate

    UserName = "johndoe@mydomain.com",
    Password = "Abc123!",
    grant_type = "password"
;

using (var client = new HttpClient())

    client.BaseAddress = new Uri("http://localhost:4321");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = client.PostAsJsonAsync("oauth/token", userToValidate).Result;
    content = response.Content.ReadAsStringAsync().Result;

我收到一个错误... "error":"unsupported_grant_type"

我必须在 C# 方面做错事。我错过了什么?

附:使用.Result 因为调试async 代码让我抓狂

【问题讨论】:

我在这篇 SO 帖子中找到了解决方案。 ***.com/questions/29246908/…。必须使用 application/x-www-form-urlencoded 而不是 JSON。 您也可以将 PostData 作为 KeyValuePair 而不是 UserToValidate 类 List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>(); postData.Add(new KeyValuePair<string, string>("grant_type", "password")); postData.Add(new KeyValuePair<string, string>("username", userName)); postData.Add(new KeyValuePair<string, string>("password", password)); @Paresh - 你能把它作为答案发布,我会接受。这样就有多种选择。谢谢。 【参考方案1】:

以下是使用 JSON 获取令牌的方法

        using (var client = new HttpClient())
        
            var email = "xyz"
            var password = "abc";
            var clientId = "123"
            var clientSecret = "456";

            client.BaseAddress = new Uri(baseUrl);

            // We want the response to be JSON.
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // Build up the data to POST.
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();

            postData.Add(new KeyValuePair<string, string>("grant_type",    "password"));
            postData.Add(new KeyValuePair<string, string>("client_id",     clientId));
            postData.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
            postData.Add(new KeyValuePair<string, string>("username",      email));
            postData.Add(new KeyValuePair<string, string>("password",      password));



            // Post to the Server and parse the response.
            HttpResponseMessage response = await client.PostAsJsonAsync("Token", postData);
            string jsonString            = await response.Content.ReadAsStringAsync();
            object responseData          = JsonConvert.DeserializeObject(jsonString);

            // return the Access Token.
            accessToken = ((dynamic)responseData).access_token;
        

        return accessToken;

【讨论】:

【参考方案2】:

内容需要进行urlencoded。 这对我来说是这样的:

            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("X-Tenant", xTenant);
            var stringContent = String.Concat("grant_type=password&username=", HttpUtility.UrlEncode(username),
                "&password=", HttpUtility.UrlEncode(password));
            var httpContent = new StringContent(stringContent, Encoding.UTF8, "application/x-www-form-urlencoded");
            var postTask = httpClient.PostAsync(apiLoginUrl, httpContent);
            postTask.Wait();
            var postResult = postTask.Result;
            var content = postResult.Content.ReadAsStringAsync().Result;
            dynamic jsonRes = JsonConvert.DeserializeObject(content);
            string access_token = jsonRes.access_token;

【讨论】:

以上是关于当 PostAsJsonAsync 时 unsupported_grant_type的主要内容,如果未能解决你的问题,请参考以下文章

将项目从 2.2 更新到 3.1(缺少程序集)或如何在 .NET Core 中使用 API POST 请求时,PostAsJsonAsync()在 .Net Core 3.1 中不起作用 [重复]

PostAsJsonAsync 未按预期运行

编译器找不到 PostAsJsonAsync 方法

ASP.NET Core 中的 PostAsJsonAsync 方法在哪里?

HttpClient.PostAsJsonAsync 无法序列化继承的属性

如何从 HttpClient.PostAsJsonAsync() 生成的 Content-Type 标头中删除 charset=utf8?