在Android模拟器中运行的应用无法对本地主机执行HTTP发布 [英] App running in Android Emulator fails to perform an HTTP Post to localhost
问题描述
我无法使用在 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屋!