在Android模拟器中运行的应用无法对本地主机执行HTTP发布 [英] App running in Android Emulator fails to perform an HTTP Post to localhost

查看:223
本文介绍了在Android模拟器中运行的应用无法对本地主机执行HTTP发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法使用在 Android模拟器中运行的应用执行 HTTP Post .

I'm unable to perform an HTTP Post with an app running in an Android Emulator.

{StatusCode:400,ReasonPhrase:错误请求",版本:1.1,内容: System.Net.Http.HttpConnection + HttpConnectionResponseContent,标头: {伺服器:Microsoft-HTTPAPI/2.0日期:2019年10月23日,星期三00:58:01 GMT连接:关闭转发:host = XXX.XXX.X.XX:XXXXX; proto = https内容类型:text/html; charset = us-ascii
内容长度:374}}

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers: { Server: Microsoft-HTTPAPI/2.0 Date: Wed, 23 Oct 2019 00:58:01 GMT Connection: close Forwarded: host=XXX.XXX.X.XX:XXXXX; proto=https Content-Type: text/html; charset=us-ascii
Content-Length: 374 }}

设置:

  • 我使用的是 Keyoti的输送机
  • 生成的IP地址. >
  • 我在 Keyoti的输送器 所需的仿真器上安装了安全证书. li>
  • 我用System.Web.Http.HttpPost交换了Microsoft.AspNetCore.Mvc.HttpPost属性
  • I'm using an IP address generated by Conveyor by Keyoti
  • I installed a security certificate on the emulator required by Conveyor by Keyoti
  • I swapped out Microsoft.AspNetCore.Mvc.HttpPost attribute with System.Web.Http.HttpPost

仿真器:

  • 成功:HTTP Get
  • 失败:HTTP发布

集成测试:

  • 成功:HTTP发布(使用相同的端点)

代码:

我编写了一个自动测试,该测试调用了相同的HTTP Post实现. 因为我通过自动测试在笔记本电脑上成功执行了相同的代码,所以我认为实际的代码不是问题:

I wrote an automated test that calls the same HTTP Post implementation. Because I executed the same code successfully on my laptop via an automated test, I don't think the actual code is the issue:

open Microsoft.AspNetCore.Mvc
open Newtonsoft.Json

[<ApiController>]
[<Route("api/[controller]")>]
type RegisterController () =
    inherit ControllerBase()

    [<System.Web.Http.HttpPost>]
    member x.Post([<FromBody>] json:string) =

        ...

摘要:

最后,我将环境隔离到了Android模拟器,而不是笔记本电脑.因此,仿真器可以成功触发HTTP Get.但是,即使我的便携式设备可以同时执行两种操作,它也无法执行HTTP Post.

In conclusion, I have isolated the environment to the Android Emulator and not my laptop. Hence, the emulator can successfully trigger an HTTP Get. However, it fails to perform a HTTP Post even though my laptop device can do both.

更新:

我从此 Xamarin Android ASP.Net Core WebAPI文档.

具体地说,我在Android模拟器上安装了另一个安全证书.

Specifically, I installed another security certificate on the Android emulator.

然后,我能够在Android模拟器上观察到HTTP Get.

I was then able to observe an HTTP Get on the Android Emulator.

但是,我仍然收到HTTP Post错误.

However, I continue to get an error for HTTP Post.

OperationCanceledException

物理设备:

如果我是从物理android设备运行该应用程序的,则请注意以下几点:

If I run the app from a physical android device I observe the following:

{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
  Date: Wed, 23 Oct 2019 13:33:20 GMT
  Server: Kestrel
  Transfer-Encoding: chunked
  Forwarded: host=xxx.xxx.x.xx:xxxxx; proto=https
  Content-Type: text/plain
}}

新更新:

我仅在服务器实现上的代码上禁用了调试,并发现了以下异常:

I disabled debugging on just my code on the server implementation and discovered the following exception:

Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: 'Bad chunk size data.'

有什么建议吗?

推荐答案

以下 基础结构:

type GlobalHttpClient private () =

    static let mutable (httpClient:System.Net.Http.HttpClient) = null

    static member val Instance = httpClient with get,set

Xamarin.Android项目:

using Android.Http;
using Android.Net;
using Javax.Net.Ssl;
using System.Net.Http;
using Xamarin.Android.Net;
using Xamarin.Forms;
using WebGatewaySupport;

[assembly: Dependency(typeof(HTTPClientHandlerCreationService_Android))]
namespace Android.Http
{
    public class HTTPClientHandlerCreationService_Android : IHTTPClientHandlerCreationService
    {
        public HttpClientHandler GetInsecureHandler()
        {
            return new IgnoreSSLClientHandler();
        }
    }

    internal class IgnoreSSLClientHandler : AndroidClientHandler
    {
        protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
        {
            return SSLCertificateSocketFactory.GetInsecure(1000, null);
        }

        protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
        {
            return new IgnoreSSLHostnameVerifier();
        }
    }

    internal class IgnoreSSLHostnameVerifier : Java.Lang.Object, IHostnameVerifier
    {
        public bool Verify(string hostname, ISSLSession session)
        {
            return true;
        }
    }
}

Xamarin.Forms应用:

switch (Device.RuntimePlatform)
{
    case Device.Android:
        GlobalHttpClient.Instance = new HttpClient(DependencyService.Get<IHTTPClientHandlerCreationService>().GetInsecureHandler());
        break;

    default:
        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
        GlobalHttpClient.Instance = new HttpClient(new HttpClientHandler());
        break;
}

客户端网关:

let postTo (baseAddress:string) (resource:string) (payload:Object) =

    GlobalHttpClient.Instance.BaseAddress <- Uri(baseAddress)
    let encoded = Uri.EscapeUriString(resource)

    let result  = GlobalHttpClient.Instance.PostAsJsonAsync(encoded, payload) |> toResult
    result

这篇关于在Android模拟器中运行的应用无法对本地主机执行HTTP发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆