【发布时间】:2018-11-19 08:10:11
【问题描述】:
我正在尝试使用以下 C# 代码发出 GET api 请求,但它失败了
System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
at System.Net.WebClient.DownloadString(Uri address)
at System.Net.WebClient.DownloadString(String address)
at Rextester.Program.callAPI()
at Rextester.Program.Main(String[] args)
请注意,相同的 API 请求通过 postman 工作。
private static void callAPI()
{
WebClient client = new WebClient();
client.UseDefaultCredentials = false;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
client.Headers.Add("Authorization", "Basic " + Base64Encode("<id:password>"));
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Environment-Id", "325");
client.QueryString.Add("query", "%7B%7D");
string reply = client.DownloadString("https://<server-api-url>");
Console.WriteLine(reply);
}
private static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
var encodedS = System.Convert.ToBase64String(plainTextBytes);
Console.WriteLine(encodedS);
return encodedS;
}
另一个奇怪的事实是,我看到在编码字符串之前打印了异常。我应该反过来想。编码后的字符串应该在之前打印,因为方法调用发生在进行 api 调用之前。
【问题讨论】:
-
使用 Postman 的 API 请求在哪里?如果您使用 Fiddler 之类的调试代理来查看实际发生的情况,我敢打赌您会发现请求不相同。
-
"<id:password>"代表什么?在基本身份验证中,字符串应为username:password,例如$"{username}:{password}"或username + ":" + password或String.Format("{0}:{1}", username,password) -
我添加了虚拟值以不暴露生产环境细节。您对身份验证字符串的格式是正确的。格式为“用户名:密码”。
-
你现在是在强迫人们猜测。您是否使用
<>?如果是,那是一个错误。如果不是,则没有其他方法可以帮助您了解问题所在。请求应该是什么样的? Fiddler 中的 Postman 请求是什么样的? WebClient 是什么样的?如果身份验证标头不同,您就会知道Base64Encode方法是错误的。如果还有其他不同,那是什么? -
感谢您为我指明正确的方向。通过提琴手,我了解到 api 调用实际上正在被重定向(http 状态代码为 307),并且在第二个请求中,授权标头没有被传递。如何在 C# 中启用重定向?
标签: c# api webclient unauthorized