WebService Post正在使用模拟器但不在设备上

时间:2016-06-03 12:42:45

标签: c# android web-services ssl xamarin

我正在尝试将数据发布到具有SSL认证的WebService。 它在模拟器中工作正常但设备仍然卡在GetResponseAsync()上。我使用HttpClient尝试使用和不使用ModernHttpClient-Library,但是它停留在PostAsync(),所以它也不起作用。

我试过另一个Thread的一个解决方案就是添加

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
        (sender, cert, chain, sslPolicyErrors) => true;

^但它也无法正常工作

在Manifest中,我添加了Internet权限。

使用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);
        }
    }

我不知道证书是问题还是别的。 他们不是自签名的。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。从那时起,时间已经过去。我不知道确切的解决方案,但现在我的代码工作正常:

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 Project - 实现上面的代码连接 Webservice
  • App Project - App.Base的参考。需要图书馆 太