我正在尝试将数据发布到具有SSL认证的Web服务。它在模拟器中工作正常,但设备一直卡在GetResponseAsync()
上。我尝试过使用HttpClient,无论是否使用ModernHttpClient-Library,但它都卡在PostAsync()
上,所以它也不起作用。
我尝试过另一个线程的一个解决方案只是添加
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
^但它也不起作用
在清单中,我添加了互联网权限。
这就是GetResponseAsync()
的代码
public async Task<Response<V>> CallWebServiceAsync<T, V>(string ticket, string url, T requestData)
{
try
{
var request = new Request<T>
{
Ticket = ticket,
Data = requestData
};
DataContractJsonSerializer serializer = new DataContractJsonSerializer(request.GetType(), this._knownTypes);
var httpRequest = WebRequest.CreateHttp(url);
httpRequest.Method = "POST";
httpRequest.UseDefaultCredentials = true;
httpRequest.ContentType = "application/json";
var requestStream = await httpRequest.GetRequestStreamAsync().ConfigureAwait(false);
serializer.WriteObject(requestStream, request);
var response = await httpRequest.GetResponseAsync().ConfigureAwait(false);
var resultStream = response.GetResponseStream();
if (resultStream == null)
{
throw new FailedWebServiceInteractionException($"Got no response stream from request. URL:{url}");
}
var jsonResponseSerializer = new DataContractJsonSerializer(typeof(Response<V>), this._knownTypes);
Response<V> result = (Response<V>)jsonResponseSerializer.ReadObject(resultStream);
resultStream.Dispose();
return result;
}
catch (Exception e)
{
throw new FailedWebServiceInteractionException("Deserialization from json response failed", e);
}
}
使用 PostAsync()
(+- ModernHttpClient) 编写代码
public async Task<Response<V>> CallWebServiceAsync<T, V>(string ticket, string url, T requestData)
{
try
{
var request = new Request<T>
{
Ticket = ticket,
Data = requestData
};
var httpClientHandler = new NativeMessageHandler
{
UseDefaultCredentials = true
};
var httpRequest = new HttpClient(httpClientHandler)
{
BaseAddress = new Uri(url)
};
httpRequest.DefaultRequestHeaders.Accept.Clear();
httpRequest.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = JsonConvert.SerializeObject(request);
var response =
await
httpRequest.PostAsync(url, new StringContent(content, Encoding.UTF8, "application/json"))
.ConfigureAwait(false);
var jsonString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<Response<V>>(jsonString);
}
catch (Exception e)
{
throw new FailedWebServiceInteractionException("Deserialization from json response failed", e);
}
}
我不知道证书是问题还是其他原因。他们不是自签名的。
我找到了解决方案。从那以后,时间一去不复返了。我不知道确切的解决方案,但这是我的代码现在可以正常工作:
var request = new Request<T>
{
Ticket = ticket,
Data = requestData
};
var httpClientHandler = new OkHttpClientHandler
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
ClientCertificateOptions = ClientCertificateOption.Automatic
};
var client = new HttpClient(httpClientHandler)
{
BaseAddress = new Uri(url),
Timeout = TimeSpan.FromSeconds(15)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var jsonRequest = this.SerializeToJson(request);
var compressedRequest = StringCompressor.CompressString(jsonRequest);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new ByteArrayContent(compressedRequest)
{
Headers = {ContentType = new MediaTypeHeaderValue("application/json")}
}
};
var httpResponse = await client.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
client.Dispose();
httpResponse.EnsureSuccessStatusCode();
var compressedResponse = await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
httpResponse.Dispose();
var jsonResponse = StringCompressor.DecompressString(compressedResponse);
var jsonResponseSerializer = new DataContractJsonSerializer(typeof(Response<V>), this._knownTypes);
Response<V> result;
using (var jsonResponseStream = this.GenerateStreamFromString(jsonResponse))
{
result = (Response<V>) jsonResponseSerializer.ReadObject(jsonResponseStream);
}
return result;
我正在使用OkHttpClient库的自编译包装器。我认为ModernHttpClient(它也引用了OkHttp)也可以工作。需要有人测试它。
重要的是要知道引用此项目的任何其他项目也需要库。
- App.Base 项目 - 实现了上述代码以连接到网络服务 App
- Project - 对 App.Base 的引用。需要图书馆太。