【发布时间】:2020-10-05 16:59:38
【问题描述】:
因为当我进行 POST 时我们切换到具有 SSL 的服务器,所以我总是收到 403 禁止错误,但是如果我使用 WebClient 它工作正常,无论如何我仍然想让它与 HttpClient 一起工作,因为我必须更改很多代码,还有一个调用使用 MultipartFormDataContent 发布文件,而我不能用 WebClient 做到这一点,在 Webclient 中,我可以选择 POST 数据或上传文件,但我需要一次调用 POST 数据和文件.
这里是 HttpClient 和 WebClient 调用的示例
HttpClient(403禁止错误)
private async void Login_Click(object sender, RoutedEventArgs e)
{
Apic = CryptoEngine.DecryptAPI(Apic);
if (API())
{
using (var content = new MultipartFormDataContent())
{
if (EmailText.Text.Contains("@") && EmailText.Text.Contains("."))
{
content.Add(new StringContent(EmailText.Text), "\"email\"");
}
else
{
content.Add(new StringContent(EmailText.Text), "\"username\"");
}
content.Add(new StringContent(PasswordText.Password), "\"password\"");
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/json");
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36");
httpClient.DefaultRequestHeaders.Add("appName", "CloudMetaPrinter");
httpClient.DefaultRequestHeaders.Add("latitude", Apic.Latitude);
httpClient.DefaultRequestHeaders.Add("longitude", Apic.Longitude);
httpClient.DefaultRequestHeaders.Add("hostname", Apic.IP);
httpClient.DefaultRequestHeaders.Add("hostType", "PC");
var httpResponse = httpClient.PostAsync(url + "/" + api + "/auth/login", content);
responseContent = await httpResponse.Result.Content.ReadAsStringAsync();
Result result = JsonConvert.DeserializeObject<Result>(responseContent);
WebClient(工作正常)
private void Login_Click(object sender, RoutedEventArgs e)
{
Apic = CryptoEngine.DecryptAPI(Apic);
if (API())
{
string data;
if (EmailText.Text.Contains("@"))
{
data = JsonConvert.SerializeObject(new
{
email = EmailText.Text,
password = PasswordText.Password
});
}
else
{
data = JsonConvert.SerializeObject(new
{
username = EmailText.Text,
password = PasswordText.Password
});
}
using (var httpClient = new WebClient { UseDefaultCredentials = true })
{
httpClient.Headers.Add("appName", "CloudMetaPrinter");
httpClient.Headers.Add("latitude", Apic.Latitude);
httpClient.Headers.Add("longitude", Apic.Longitude);
httpClient.Headers.Add("hostname", Apic.IP);
httpClient.Headers.Add("hostType", "PC");
httpClient.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
var httpResponse = httpClient.UploadData(url + "/" + api + "/auth/login", "POST", Encoding.UTF8.GetBytes(data));
var str = System.Text.Encoding.Default.GetString(httpResponse);
Result result = JsonConvert.DeserializeObject<Result>(str);
我尝试在标头中进行更改,UseDefaultCredentials = true 等,但没有任何效果。
编辑:我使用 .net core 3.0 Edit2:GetAsync 与 HttpClient 工作正常,问题仅在于 PostAsync。
好的,所以我尝试与 fiddler 进行比较并更改一些内容,以便 httpclient 调用更像 webclient,但我仍然得到 403 左边是 WebClient,右边是 HttpClient Compare image
【问题讨论】:
-
无论代码如何,您都可以轻松使用fiddler查看发布到服务器时两种方法的不同之处,以帮助您解决未来的问题
-
您在每种情况下都使用不同的凭据。使用 WebClient,您使用的是 Windows 身份验证。使用 HttpClient,根本不需要身份验证。您甚至没有传递基本身份验证标头。更改 HttpClient 代码以也使用 Windows 身份验证
-
这两个 sn-ps 也非常不同 - 第一个发布表单,第二个发送 JSON 字符串。为什么您希望它们表现相同?
-
@PanagiotisKanavos 在使用 SSL 服务器之前 HttpClient 起作用了,所以我猜是因为 Windows 身份验证,但我无法找到有关如何更改 HttpClient 以使用 Windows 身份验证的信息
-
@mortb 不,他们最终使用 WebClient,我需要使用 HttpClient。
标签: c# visual-studio