Xamarin & IIS LocalHost WebApi 给出错误 - System.Net.Http.HttpRequestException: '网络子系统已关闭'

Posted

技术标签:

【中文标题】Xamarin & IIS LocalHost WebApi 给出错误 - System.Net.Http.HttpRequestException: \'网络子系统已关闭\'【英文标题】:Xamarin & IIS LocalHost WebApi gives error - System.Net.Http.HttpRequestException: 'Network subsystem is down'Xamarin & IIS LocalHost WebApi 给出错误 - System.Net.Http.HttpRequestException: '网络子系统已关闭' 【发布时间】:2020-04-07 14:53:09 【问题描述】:

我在这里有 2 个应用程序。一个是 Xamarin 应用程序,另一个是 Asp.Net MVC 应用程序,它具有 WebApi 以连接到 SqlServer 数据库“其中数据库位于某个 IP 地址 xxx.xxx.xxx.xxx 的托管网站上”。

我在 IIS 中本地运行 MVC 应用程序,然后在 IIS 中启动网站后,我从 Visual Studio 的第二个实例运行 Xamarin 应用程序。

首先,我不认为 MVC WebApi 被调用,因为我尝试将断点放在那里,但它没有出现。我不知道为什么。因为我对 Winforms 和 MVC 应用程序 (WebApi) 做了同样的事情,所以至少 WebApi 被调用了,我在 MVC 应用程序中看到了断点。

现在在 Xamarin 中出现此错误

System.Net.Http.HttpRequestException: 'Network subsystem is down'

在行中

var responseTask = await client.GetAsync("ConnectToAscDatabase");

我在 Xamarin 应用程序的 MainPage.cs 中有这段代码

        private async void Button_OnClicked(object sender, EventArgs e)
        
            HttpClientHandler handler = new HttpClientHandler();
            handler.UseDefaultCredentials = true;
            using (var client = new HttpClient(handler))
            
                client.BaseAddress = new Uri("http://localhost:49252/api/");

                // !!! This Line gives the error System.Net.Http.HttpRequestException: 'Network subsystem is down'
                var responseTask = await client.GetAsync("ConnectToAscDatabase");

                var readTask = responseTask.Content.ReadAsAsync<Microsoft.Data.SqlClient.SqlConnection>();
                SqlConnection con = readTask.Result;
                var staty = con.State;
            
        

这是一个 WebApi

        public class ConnectToAscDatabaseController : ApiController
        
            public async Task<Microsoft.Data.SqlClient.SqlConnection> Get()
            
                string SqlServer_ServerPath_Server = "SomeServer";
                string SqlServer_Database_Server = "SomeDatabase";
                string SqlServer_User_Server = "SomeUser";
                string SqlServer_Password_Server = "SomePassword";
                int timeOutInSeconds = 15;
                string connectionString = "data source=" + SqlServer_ServerPath_Server + ";" + "initial catalog=" + SqlServer_Database_Server + ";" + "user id=" + SqlServer_User_Server + ";" + "Password=" + SqlServer_Password_Server + ";" + "Trusted_Connection=false" + ";" + "Connection Timeout=" + timeOutInSeconds + ";" + "Persist Security Info=False";
                SqlConnection con = new SqlConnection(connectionString);
                con.Open();
                return con;
            
        

【问题讨论】:

你用的是安卓模拟器吗? 不要使用本地主机。使用您的服务器的 IP。并确保您的本地 IIS 配置为允许外部连接 是的,我正在使用 android 模拟器 "localhost" 会告诉安卓模拟器连接回它自己,而不是你的本地服务器。这就是您应该使用 IP 的原因。 Jason 我尝试使用我的实时网站 URL client.BaseAddress = new Uri("example.com/api/"); 我没有收到错误,但返回的连接对象包含所有 ConnectionString、State 和 ALL属性为 NULL(更具体地说,它说“System.NullReferenceException:对象引用未设置为对象的实例”与 Connection 对象中的所有值相反。 【参考方案1】:

根据本文档,Android's Network Address Space 负责,因为除了 IP 地址“10.0.2.2”之外,没有从模拟器到本地计算机的直接连接。您可以附加您的端口号来定位您尝试访问的任何服务。

还值得注意的是,对于使用自签名证书运行的服务,由于信任问题,您仍然可能无法获得连接,因为 Android 和 ios 不会接受与使用自签名证书运行的服务的连接。 Read more from here.

我使用以下代码来解决这些问题(在 Android 上):

共享项目(添加如下接口):

using System.Net.Http;

namespace DemoApp.Services

    public interface IHttpClientHandlerService
    
        HttpClientHandler GetInsecureHandler();
    

Android 项目(添加以下类):

using DemoApp.Droid.Services;
using DemoApp.Services;
using System.Net.Http;
using Xamarin.Forms;

[assembly: Dependency(typeof(HttpClientHandlerService))]
namespace DemoApp.Droid.Services

    public class HttpClientHandlerService : IHttpClientHandlerService
    
        public HttpClientHandler GetInsecureHandler()
        
            HttpClientHandler handler = new HttpClientHandler
            
                ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
                
                    if (cert.Issuer.Equals("CN=localhost"))
                        return true;
                    return errors == System.Net.Security.SslPolicyErrors.None;
                
            ;
            return handler;
        
    

现在,您可以在您的代码中使用以下代码创建一个新的 HttpClient:

#if DEBUG
    HttpClientHandler insecureHandler = DependencyService.Get<IHttpClientHandlerService>().GetInsecureHandler();
    HttpClient client = new HttpClient(insecureHandler);
#else
    HttpClient client = new HttpClient();
#endif

注意:创建 HttpClient 有更好的方法(例如使用依赖注入和 IHttpClientFactory),读者可以选择最适合它们的方法。

对于HttpClient的BaseAddress,也可以使用如下代码:

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"BaseAddress/api/todoitems/";

其中端口 5000 可能是访问您的服务的端口,而 todoitems 可能是要调用的 api url。

【讨论】:

感谢您的回复。我设法从docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/… 获得了相同的信息,但您的评论很容易理解。不幸的是,即使使用此解决方案,我也没有让模拟器使用 https -connection,所以最终我决定在开发中只使用 http 并将 https 保留为实时版本。【参考方案2】:

根据您的描述,您想在 Xamarin.Forms 中使用 web api 显示数据,这方面的文章很多,您可以看看:

https://www.c-sharpcorner.com/article/how-to-fetch-data-from-web-api-using-xamarin-forms/

您需要确保 Web API 项目已启动并正在运行,因为 Xamarin 应用将调用 WebAPI 来访问数据。

有关使用实体框架构建 ASP.NET Web API 并从 SQL 服务器检索数据的更多详细信息,您还可以查看:

https://medium.com/better-programming/building-a-restful-api-with-asp-net-web-api-and-sql-server-ce7873d5b331

【讨论】:

以上是关于Xamarin & IIS LocalHost WebApi 给出错误 - System.Net.Http.HttpRequestException: '网络子系统已关闭'的主要内容,如果未能解决你的问题,请参考以下文章

WordPress建立MySQL数据库连接IIS10时出错[重复]

Cors Policy 问题 Blazor WASM、Web API 和 Identity Server 4 和 IIS

我是xp系统安装了IIS,运行的时候显示: 您指定的网页无法访问! 错误类型:500

多表离线同步 Xamarin.Forms & Azure

Xamarin.Forms 背景图片

给mysql配置phpmyadmin可视化管理工具