Xamarin.Forms 中的 HttpClient 抛出 "An error occurred while sending the request."
HttpClient in Xamarin.Forms throwing "An error occurred while sending the request."
我使用 Xamarin.Forms 在 Windows(UWP) 和 Android 上开发多平台应用程序。我还在我工作的企业的 LAN 上使用来自 ERP 运行 的 WebService。此 WebService 在 C# 中使用 WebRequest 的正常请求中可用,并且工作正常。但是 Xamarin 更喜欢使用具有多个平台的 HttpClient 和异步方法。 WebRequest 确实不适用于 android,它锁定了 UWP 中的 UI。
所以我创建了一个类似于 MSDN 中的 RestService,但无法使请求响应。只要我将 WebRequest 请求放在 HttpClient 请求之前,它就可以工作,并且我收到了我想要的 XML。
如果我只放置 HttpClient 请求,它会抛出一个简单的错误 → HttpRequestException,只是(“发送请求时发生错误。”)。
InnerException 是 →“找不到与此错误代码关联的文本。证书颁发机构无效或不正确。”
目标是多平台,所以我认为需要 HttpClient,我已经尝试过进行证书验证并在许多论坛上搜索都没有找到答案!!
希望有人能帮助我!
使用 WebRequest 请求
public string Request(string uri)
{
string responseFromServer = "";
ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
WebRequest request = WebRequest.Create(uri);
request.Credentials = new NetworkCredential(user, pswd);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (((HttpWebResponse)response).StatusDescription == "OK")
{
Stream dataStream;
using (dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
}
}
response.Close();
return responseFromServer;
}
我用 HttpClient 请求
//Constructor
public RestService()
{
//Authentification for the request header
user = "**";
pswd = "*****";
society= "*****";
user = "%CP1252%" + Base64Encode(user + "@@" + society+ "@@00000");
pswd = Base64Encode(pswd );
var authData = string.Format("{0}{1}", user, mdp);
client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authData);
//Security protocol
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
}
//Request method
public async Task<string> GetDatas(string url)
{
Uri uri = new Uri(string.Format(url, string.Empty));
string content = "";
try
{
HttpResponseMessage response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
content = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
return content;
}
我在 MockDataStore 中请求填写 objects
的列表
public async Task<IEnumerable<Operation>> GetItemsAsync(bool forceRefresh = false)
{
GetOperations(); // call WebRequest Method
await GetOperationsAsync(); // call HttpClient Method
return await Task.FromResult(Operations);
}
尝试使用 GetStringAsync
自定义 httpclient 实例的默认 headers
client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authData);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Mozilla", "5.0"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("AppleWebKit", "537.36"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Chrome", "91.0.4472.114"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Safari", "537.36"));
client.DefaultRequestHeaders.Host = "srverp:****";
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("fr-FR"));
client.DefaultRequestHeaders.Connection.Add("keep-alive");
client.DefaultRequestHeaders.Pragma.Add(new NameValueHeaderValue("no-cache"));
尝试使用 sendAsync
自定义 headers 请求
var request = new HttpRequestMessage()
{
RequestUri = uri,
Method = HttpMethod.Get,
Headers = {
{ HttpRequestHeader.Authorization.ToString(), "Basic " + authData},
{ HttpRequestHeader.Accept.ToString(), "application/xml" }
},
};
var task = client.SendAsync(request).ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var tmp = response.Content.ReadAsStringAsync();
content = tmp.Result;
});
task.Wait();
通过在 Handler 实例中添加 httpClient 的 header 解决了问题,如下所示:
public HttpClient HttpclientAccount
{
get
{
client = client ?? new HttpClient
(
new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
//bypass
return true;
},
}
, false
);
// authentification headers
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{user}:{mdp}")));
return client;
}
}
使用此方法,认证有效,反应良好!
我使用 Xamarin.Forms 在 Windows(UWP) 和 Android 上开发多平台应用程序。我还在我工作的企业的 LAN 上使用来自 ERP 运行 的 WebService。此 WebService 在 C# 中使用 WebRequest 的正常请求中可用,并且工作正常。但是 Xamarin 更喜欢使用具有多个平台的 HttpClient 和异步方法。 WebRequest 确实不适用于 android,它锁定了 UWP 中的 UI。
所以我创建了一个类似于 MSDN 中的 RestService,但无法使请求响应。只要我将 WebRequest 请求放在 HttpClient 请求之前,它就可以工作,并且我收到了我想要的 XML。
如果我只放置 HttpClient 请求,它会抛出一个简单的错误 → HttpRequestException,只是(“发送请求时发生错误。”)。 InnerException 是 →“找不到与此错误代码关联的文本。证书颁发机构无效或不正确。”
目标是多平台,所以我认为需要 HttpClient,我已经尝试过进行证书验证并在许多论坛上搜索都没有找到答案!!
希望有人能帮助我!
使用 WebRequest 请求
public string Request(string uri)
{
string responseFromServer = "";
ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
WebRequest request = WebRequest.Create(uri);
request.Credentials = new NetworkCredential(user, pswd);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (((HttpWebResponse)response).StatusDescription == "OK")
{
Stream dataStream;
using (dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
}
}
response.Close();
return responseFromServer;
}
我用 HttpClient 请求
//Constructor
public RestService()
{
//Authentification for the request header
user = "**";
pswd = "*****";
society= "*****";
user = "%CP1252%" + Base64Encode(user + "@@" + society+ "@@00000");
pswd = Base64Encode(pswd );
var authData = string.Format("{0}{1}", user, mdp);
client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authData);
//Security protocol
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
}
//Request method
public async Task<string> GetDatas(string url)
{
Uri uri = new Uri(string.Format(url, string.Empty));
string content = "";
try
{
HttpResponseMessage response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
content = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
return content;
}
我在 MockDataStore 中请求填写 objects
的列表public async Task<IEnumerable<Operation>> GetItemsAsync(bool forceRefresh = false)
{
GetOperations(); // call WebRequest Method
await GetOperationsAsync(); // call HttpClient Method
return await Task.FromResult(Operations);
}
尝试使用 GetStringAsync
自定义 httpclient 实例的默认 headersclient = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authData);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Mozilla", "5.0"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("AppleWebKit", "537.36"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Chrome", "91.0.4472.114"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Safari", "537.36"));
client.DefaultRequestHeaders.Host = "srverp:****";
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("fr-FR"));
client.DefaultRequestHeaders.Connection.Add("keep-alive");
client.DefaultRequestHeaders.Pragma.Add(new NameValueHeaderValue("no-cache"));
尝试使用 sendAsync
自定义 headers 请求var request = new HttpRequestMessage()
{
RequestUri = uri,
Method = HttpMethod.Get,
Headers = {
{ HttpRequestHeader.Authorization.ToString(), "Basic " + authData},
{ HttpRequestHeader.Accept.ToString(), "application/xml" }
},
};
var task = client.SendAsync(request).ContinueWith((taskwithmsg) =>
{
var response = taskwithmsg.Result;
var tmp = response.Content.ReadAsStringAsync();
content = tmp.Result;
});
task.Wait();
通过在 Handler 实例中添加 httpClient 的 header 解决了问题,如下所示:
public HttpClient HttpclientAccount
{
get
{
client = client ?? new HttpClient
(
new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
//bypass
return true;
},
}
, false
);
// authentification headers
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.UTF8.GetBytes($"{user}:{mdp}")));
return client;
}
}
使用此方法,认证有效,反应良好!