C# 使用 Nest API Restful 使用 HttpClient 进行身份验证
C# Works with Nest API Restful Auth using HttpClient
我还是 C# 的新手,我确信我没有正确使用 HttpClient 库。我正在尝试使用 Works With Nest API 进行身份验证,以便我可以 read/write 向恒温器发出请求。下面是我用来验证的代码:
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"}
您正在 return 您正在从您的操作方法返回完整的响应消息,包括它的所有属性和值。相反,您应该只阅读其内容和 return。如果您愿意,可以找到一篇关于使用内置 .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>
)作为 return 类型。 你不应该 return 响应对象。
- 我是直接用
PostAsync()
方法,相关内容为FormUrlEncodedContent
,而不是先建一个HttpRequestMessage
再用SendAsync()
.
- 另外不要忘记检查您的请求是否成功!否则,您可能会 return 从您的操作方法中获取错误消息。
- 我只是以
ReadAsStringAsync()
和 return Content()
为例。
请注意,您对 Nest API 的请求有问题,因为它 returns 400 Bad Request
。您应该能够从内容中的错误消息中准确地得出什么。 ;)
编辑
我快速浏览了 Nest API,我认为您为 code
提供了错误的值。我认为您应该先调用另一个 API 方法来检索授权码,然后再将其交换为访问令牌(如 here 所示),而不是指定您的 PIN 码。
我还是 C# 的新手,我确信我没有正确使用 HttpClient 库。我正在尝试使用 Works With Nest API 进行身份验证,以便我可以 read/write 向恒温器发出请求。下面是我用来验证的代码:
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"}
您正在 return 您正在从您的操作方法返回完整的响应消息,包括它的所有属性和值。相反,您应该只阅读其内容和 return。如果您愿意,可以找到一篇关于使用内置 .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>
)作为 return 类型。 你不应该 return 响应对象。 - 我是直接用
PostAsync()
方法,相关内容为FormUrlEncodedContent
,而不是先建一个HttpRequestMessage
再用SendAsync()
. - 另外不要忘记检查您的请求是否成功!否则,您可能会 return 从您的操作方法中获取错误消息。
- 我只是以
ReadAsStringAsync()
和return Content()
为例。
请注意,您对 Nest API 的请求有问题,因为它 returns 400 Bad Request
。您应该能够从内容中的错误消息中准确地得出什么。 ;)
编辑
我快速浏览了 Nest API,我认为您为 code
提供了错误的值。我认为您应该先调用另一个 API 方法来检索授权码,然后再将其交换为访问令牌(如 here 所示),而不是指定您的 PIN 码。