仍然是C#的新手,我确信我没有正确使用HttpClient库。我正在尝试使用Works With Nest API进行身份验证,以便我可以读取/写入恒温器的请求。以下是我用于验证的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;
namespace iConnect.Controllers
{
public class NestController : Controller
{
static HttpClient client = new HttpClient();
public IActionResult Index()
{
return View();
}
public async Task<HttpResponseMessage> GetNestAuthCode()
{
// Nest Pin Code
String pincode = "MYPING";
String clientID = "My-Client-ID";
String clientSecret = "MySecretString";
String grantType = "authorization_code";
client.BaseAddress = new Uri("https://api.home.nest.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token");
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("code", pincode)
, new KeyValuePair<string, string>("client_id", clientID)
, new KeyValuePair<string, string>("client_secret", clientSecret)
, new KeyValuePair<string, string>("grant_type", grantType)
};
//var content = new FormUrlEncodedContent(data);
//await content.ReadAsByteArrayAsync();
//content.Add(data);
request.Content = new FormUrlEncodedContent(data);
//HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content);
HttpResponseMessage response = await client.SendAsync(request);
return response;
}
}
}
当我转到localhost:9387 / Nest / GetAuthCode时,我收到以下JSON响应:
{
"version":{
"major":1,
"minor":1,
"build":-1,
"revision":-1,
"majorRevision":-1,
"minorRevision":-1
},
"content":{
"headers":[
{
"key":"Content-Type",
"value":[
"application/json"
]
}
]
},
"statusCode":400,
"reasonPhrase":"Bad Request",
"headers":[
{
"key":"Connection",
"value":[
"keep-alive"
]
}
],
"requestMessage":{
"version":{
"major":1,
"minor":1,
"build":-1,
"revision":-1,
"majorRevision":-1,
"minorRevision":-1
},
"content":{
"headers":[
{
"key":"Content-Type",
"value":[
"application/x-www-form-urlencoded"
]
},
{
"key":"Content-Length",
"value":[
"130"
]
}
]
},
"method":{
"method":"POST"
},
"requestUri":"https://api.home.nest.com/oauth2/access_token",
"headers":[
{
"key":"Accept",
"value":[
"application/json"
]
}
],
"properties":{
}
},
"isSuccessStatusCode":false
}
非常感谢任何帮助。谢谢。
修改
我做了以下更改并得到以下回复(这不是我的预期):
代码:
public async Task<ActionResult> GetNestAuthCode()
{
// Nest Pin Code
String pincode = "MYPING";
String clientID = "My-Client-ID";
String clientSecret = "MySecretString";
String grantType = "authorization_code";
client.BaseAddress = new Uri("https://api.home.nest.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/access_token");
var data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("code", pincode)
, new KeyValuePair<string, string>("client_id", clientID)
, new KeyValuePair<string, string>("client_secret", clientSecret)
, new KeyValuePair<string, string>("grant_type", grantType)
};
//var content = new FormUrlEncodedContent(data);
//await content.ReadAsByteArrayAsync();
//content.Add(data);
//request.Content = new FormUrlEncodedContent(data);
//HttpResponseMessage response = await client.PostAsync(client.BaseAddress, content);
var response = await client.PostAsync("oauth2/access_token",
new FormUrlEncodedContent(data));
var content = await response.Content.ReadAsStringAsync();
return Content(content);
}
响应:
{"error":"oauth2_error","error_description":"authorization code not found","instance_id":"f64d5268-8bec-4799-927c-e53454ed96d5"}
答案 0 :(得分:1)
您将从操作方法返回整个响应消息及其所有属性和值。相反,您应该只阅读其内容并将其返回。如果您愿意,可以找到关于使用内置.NET HttpClient
权限here的好文章。
我会做的是以下内容:
public async Task<IActionResult> GetNestAuthCode()
{
// HttpClient setup...
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("code", "MYPING"),
new KeyValuePair<string, string>("client_id", "My-Client-ID"),
new KeyValuePair<string, string>("client_secret", "MySecretString"),
new KeyValuePair<string, string>("grant_type", "authorization_code")
});
var response = await client.PostAsync("oauth2/access_token", content);
// Or check instead with IsSuccessStatusCode
response.EnsureSuccessStatusCode();
// ReadAsStringAsync() is just an example here
var responseContent = await response.Content.ReadAsStringAsync();
return Content(responseContent);
}
请注意......
IActionResult
(或实际Task<IActionResult>
)作为返回类型。 您不应该返回响应对象。 PostAsync()
方法,相关内容为FormUrlEncodedContent
,而不是先构建HttpRequestMessage
并使用SendAsync()
。ReadAsStringAsync()
和return Content()
为例。请注意,您对Nest API的请求有问题,因为它返回400 Bad Request
。您应该能够从内容中的错误消息中精确地得到什么。 ;)
修改强>
我非常快速地了解了Nest API,我认为您为code
提供了错误的值。我认为您应该首先调用另一个API方法来检索授权代码,然后才能将其替换为访问令牌(如here所示),而不是指定您的PIN码。