我正在尝试发送http post请求以获取api令牌。如果成功,则应返回访问令牌,令牌类型(承载)和expires_in的字符串值。
我所拥有的代码是一个通用的代码,我期待它能够正常工作。但由于某些原因,它抛出400“异常远程服务器返回错误。错误请求”。我一直在努力解决这个问题,但结果并没有改变。
当我调试代码并在“输出”窗口中查看结果时,有一个关于数据流的例外,说“此流不支持搜索操作”
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
我怀疑是因为postData,它的编码方式。我的客户秘密就像:
克/ gOvqf5R + FTZZXbwsCbp0WsQjF9B0bl87IBQ8VAJ2Q =
它是否对秘密本身的字符进行编码,以便构造错误的请求?
我也在POSTMAN上尝试了这个,它产生了一个结果,所以没有api。它再次归结为请求内容。这是一个控制台应用程序。我正在粘贴下面的代码,我很感谢您的帮助。
public static APIModel GenerateApiKey()
{
var appSettings = ConfigurationManager.AppSettings;
try
{
var urlToCall = string.Format("https://app.example.com/token");
var uri = new Uri(urlToCall);
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
string postData = "grant_type=client_credentials&client_id=" + appSettings["my_client_id"] + "&client_secret=" + appSettings["my_client_secret"];
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
var response = (HttpWebResponse)request.GetResponse();
APIModel bearerToken;
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
string jsonFromServer = sr.ReadToEnd();
bearerToken = JsonConvert.DeserializeObject<APIModel>(jsonFromServer);
}
response.Close();
return bearerToken;
}
catch (Exception e)
{
throw new Exception("Error getting a response from API " + e.Message);
}
}
答案 0 :(得分:2)
由于您发送了某种不正确的数据,远程服务器会给您400错误。您可能能够获得响应并找出确切的错误 - 远程服务器很可能会为您提供更多信息。但是,我可以看到您的帖子数据存在一个问题 - 客户端密钥需要进行URL编码。查看它的内容,您会看到它以=
符号结尾。这将被解释为一个特殊的角色。我也想更明确地创建字符串,所以这对你有用:
var postItems = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", "client_credentials"),
new KeyValuePair<string, string>("client_secret", "client_credentials"),
};
string postData = string.Join("&",
postItems.Select (kvp =>
string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
答案 1 :(得分:0)
客户端ID和机密必须在形成表单数据时单独进行url编码。更新了postData:
string postData = "grant_type=client_credentials&client_id=" + HttpUtility.UrlEncode(appSettings["my_client_id"]) + "&client_secret=" + HttpUtility.UrlEncode(appSettings["my_client_secret"]);