从 Flutter 请求 ASP.Net Core 3.0 的错误请求 400

sko*_*jen 2 android flutter asp.net-core

我正在尝试连接 Flutter 的 HttpClient 以从我在 ASP.Net Core 3.0 上运行的本地服务器获取数据。问题是我每次尝试时都会收到错误 400(错误请求)。

这是颤振代码:

    String token = await SharedPreferencesService.getStringFromSF('idToken');
    var client = new HttpClient();
    client.badCertificateCallback =
        (X509Certificate cert, String host, int port) => true;

    HttpClientRequest request =
        await client.getUrl(Uri.parse('https://10.0.2.2:44383/weatherforcast'));
    request.headers.add('idToken', token);

    HttpClientResponse response = await request.close();
    String reply = await response.transform(utf8.decoder).join();
Run Code Online (Sandbox Code Playgroud)

asp.net core 3.0 端点:

    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet]
        public User Get()
        {
            return new User { UserId = 1332, Username = "Michal" };
        }
    }
Run Code Online (Sandbox Code Playgroud)

错误

<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Hostname</h2>
<hr><p>HTTP Error 400. The request hostname is invalid.</p>
Run Code Online (Sandbox Code Playgroud)

我可以确认我在浏览器和邮递员中获取了数据。感谢您的帮助。

sko*_*jen 7

好的,我通过逐步调试解决了这个问题。

Android 似乎不喜欢自签名证书,因此我最终无法将其设置为使用 HTTPS。

我所做的是我让它与唯一的 HTTP 一起工作,这些是步骤:

  1. 将 IIS 更改为您本地的运行时环境(默认为项目名称)
  2. app.UseHttpsRedirection();在服务器配置方法中删除

我们现在启用了对服务器的 HTTP 请求。接下来是通过我们的本地运行时环境运行服务器(我们可以在 VS 中的调试按钮中更改)。

现在,我们应该能够使用 http 请求(例如http://localhost:5000/weatherforcast. 请记住,ASP.NET Core 3.0 默认在端口 5001 上提供 HTTPS,在 5000 上提供 HTTP。

接下来,Android 使用服务器运行的本地机器 IP 的别名,因此localhost:<port>我们必须编写而不是编写10.0.2.2:<port>

最后,我将客户端中的 api 调用简化为如下所示:

static Future<Profile> getUserProfile() async {
    String url = 'http://10.0.2.2:5000/weatherforecast';
    final reply = await http.get('$url');
    var responseJson = json.decode(reply.body);
    return Profile.fromJson(responseJson);
  }
Run Code Online (Sandbox Code Playgroud)


Hen*_*olo 5

为了解决这个问题,我们首先需要了解Android模拟器的工作原理:

\n
\n

您应该了解的第一个提示是 Android 模拟器(虚拟设备)有自己的网络。因此 Google 定义了一个神奇的 IP\n地址 \xe2\x80\x9c10.0.2.2\xe2\x80\x9d。如果您尝试浏览到此 IP 地址,\n请求将被路由到\n主机的 \xe2\x80\x9c127.0.0.1\xe2\x80\x9d 环回适配器。(稍后我会给你证明魔法路由。)

\n
\n

很简单:如果你输入localhost地址,它就会连接到自己的 Android 模拟器网络。因此,如果我们输入10.0.0.2,则转换为127.0.0.1,我们就能够访问我们的机器网络。

\n

问题是IIS 没有对地址https上的请求127.0.0.1:port进行绑定,而只对localhost:port. 亲自尝试一下:运行 .NET Core API,转到浏览器并输入127.0.0.1:port. 您将直接收到400 - Bad Request错误。

\n

那么,如何让IIS识别该127.0.0.1:port地址呢?

\n

您将不得不弄乱 ISS Express 配置文件并手动添加绑定。按照步骤:

\n

1 - 打开您的applicationHost.config项目文件。在VS2019中,它在里面$(solutionDir)\\.vs\\{projectName}\\config\\applicationhost.config

\n

.vs文件夹是隐藏的,因此请确保让文件资源管理器显示隐藏目录。\n对​​于其他 Visual Studio 版本,请查看此链接:IIS Express 配置/元数据库文件在哪里找到?

\n

2 - CRTL + F 进行搜索port:localhost,您将找到已为您的项目配置的绑定线。

\n

https3 - 插入协议和地址行127.0.0.1:port。您的绑定现在应该如下所示:

\n
<bindings>\n      <binding protocol="https" bindingInformation="*:port:localhost" /> \n      <binding protocol="https" bindingInformation="*:port:127.0.0.1" /> <!-- here is your line --> \n      <binding protocol="http" bindingInformation="*:otherPort:localhost" />\n</bindings>\n
Run Code Online (Sandbox Code Playgroud)\n

现在,返回您的浏览器并尝试访问127.0.0.1:port. 你应该没有任何错误。您的 Flutter 应用程序也是如此。享受!

\n

参考资料:如何让android模拟器访问IIS Express?- 莱克斯工作室

\n