從 Android 模擬器和 iOS 模擬器 連線 至本機 Web 服務
許多行動裝置和傳統型應用程式都會取用 Web 服務。 在軟體開發階段,通常會在本機部署 Web 服務,並從在 Android 模擬器或 iOS 模擬器中執行的應用程式取用 Web 服務。 這可避免將 Web 服務部署至託管端點,並啟用簡單的偵錯體驗,因為應用程式和 Web 服務都在本機執行。
在 Windows 或 MacCatalyst 上執行的 .NET 多平台應用程式 UI (.NET MAUI) 應用程式,只要您已 信任開發憑證,即可取用透過 HTTP 或 HTTPS 在本機執行的 ASP.NET Core Web 服務,而不需要任何額外的工作。 不過,當應用程式在 Android 模擬器或 iOS 模擬器中執行時,需要額外的工作,而且程式會根據 Web 服務是透過 HTTP 或 HTTPS 執行而有所不同。
本機計算機位址
Android 模擬器和 iOS 模擬器都可讓您存取在本機電腦上透過 HTTP 或 HTTPS 執行的 Web 服務。 但是每部電腦的本機電腦位址都不一樣。
Android
Android 模擬器的每個執行個體都會與您的開發電腦網路介面隔離,並在虛擬路由器背後執行。 因此,模擬的裝置看不到您的開發電腦,或網路上的其他模擬器執行個體。
但是,每個模擬器的虛擬路由器都會管理一個特殊的網路空間,其中包括預先配置的位址,而 10.0.2.2
位址為您主機回送介面的別名 (在您的開發電腦上為 127.0.0.1)。 因此,假設本機 Web 服務透過 /api/todoitems/
相對 URI 公開 GET 作業,Android 模擬器上執行的應用程式可以藉由將 GET 要求傳送至 http://10.0.2.2:<port>/api/todoitems/
或 https://10.0.2.2:<port>/api/todoitems/
來取用作業。
iOS
iOS 模擬器會使用主機電腦網路。 因此,在模擬器中執行的應用程式可以透過電腦IP位址或 localhost
主機名連線到本機電腦上執行的Web服務。 例如,假設本機 Web 服務透過 /api/todoitems/
相對 URI 公開 GET 作業,在 iOS 模擬器上執行的應用程式可以藉由將 GET 要求傳送至 http://localhost:<port>/api/todoitems/
或 https://localhost:<port>/api/todoitems/
來取用作業。
注意
從 Windows 在 iOS 模擬器中執行 .NET MAUI 應用程式時,應用程式會顯示在 Windows 的遠端 iOS 模擬器中。 不過,應用程式正在配對的 Mac 上執行。 因此,對於在 Mac 上執行的 iOS 應用程式,在 Windows 中執行的 Web 服務沒有 localhost 存取權。
透過 HTTP 執行的本機 Web 服務
在 Android 模擬器或 iOS 模擬器中執行的 .NET MAUI 應用程式,可以使用透過 HTTP 在本機執行的 ASP.NET Core Web 服務。 您可以藉由設定 .NET MAUI 應用程式專案和 ASP.NET Core Web 服務專案,以允許純文本 HTTP 流量來達成此目的。
在 .NET MAUI 應用程式中定義本機 Web 服務的 URL 的程式代碼中,請確定 Web 服務 URL 會指定 HTTP 配置,以及正確的主機名。 類別 DeviceInfo
可用來偵測應用程式執行的平臺。 接著可以設定正確的主機名,如下所示:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
如需 類別 DeviceInfo
的詳細資訊,請參閱 裝置資訊。
此外,若要在 Android 上執行您的應用程式,您必須新增必要的網路安全性設定,並在 iOS 上執行您的應用程式,您必須退出宣告 Apple Transport Security (ATS)。 如需詳細資訊,請參閱 Android 網路安全性設定 和 iOS ATS 設定。
您也必須確定您的 ASP.NET Core Web 服務已設定為允許 HTTP 流量。 這可以透過將 HTTP 配置檔新增至 profiles
launch 的 區段來達成 設定.json 在您的 ASP.NET Core Web 服務專案中:
{
...
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "api/todoitems",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
...
}
}
在 Android 模擬器或 iOS 模擬器中執行的 .NET MAUI 應用程式,接著可以使用透過 HTTP 在本機執行的 ASP.NET Core Web 服務,前提是 Web 服務是以配置檔啟動 http
。
Android 網路安全性設定
若要在 Android 上啟用純文字本機流量,您必須建立網路安全組態檔。 將名為 network_security_config.xml 的新 XML 檔案新增至 .NET MAUI 應用程式專案中的 Platform\Android\Resources\xml 資料夾,即可達成此目的。 XML 檔案應該指定下列組態:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
注意
確定network_security_config.xml檔案的 建置 動作已設定為 AndroidResource。
然後,在 .NET MAUI 應用程式專案中 Platform\Android\AndroidManifest.xml 檔案的應用程式節點上設定 networkSecurityConfig 屬性:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config" ...>
...
</application>
</manifest>
如需網路安全組態檔的詳細資訊,請參閱 developer.android.com 上的網路安全性 設定。
iOS ATS 設定
若要在 iOS 上啟用純文字本機流量,您應該退出宣告 .NET MAUI 應用程式中的 Apple Transport Security (ATS)。 將下列組態新增至 .NET MAUI 應用程式專案中的 Platform\iOS\Info.plist 檔案,即可達成此目的:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
如需 ATS 的詳細資訊,請參閱防止 developer.apple.com 上的不安全網路 連線。
透過 HTTPS 執行的本機 Web 服務
在 Android 模擬器或 iOS 模擬器中執行的 .NET MAUI 應用程式,可以使用透過 HTTPS 在本機執行的 ASP.NET Core Web 服務。 開啟此作業的程式如下所示:
- 信任您電腦上的自我簽署開發憑證。 如需詳細資訊,請參閱 信任您的開發憑證。
- 指定本機電腦的位址。 如需詳細資訊,請參閱指定本機電腦位址。
- 繞過本機開發憑證安全性檢查。 如需詳細資訊,請參閱繞過憑證安全性檢查。
我們會輪流討論每個項目。
信任您的開發憑證
安裝 .NET Core SDK 會將 ASP.NET Core HTTPS 開發憑證安裝到本機使用者證書存儲。 但是,雖然已安裝憑證,但憑證不受信任。 若要信任憑證,請執行下面的一次性步驟,以執行 dotnet dev-certs
工具:
dotnet dev-certs https --trust
下列命令會提供 dev-certs
工具的說明:
dotnet dev-certs https --help
或者,當您使用 HTTPS 執行 ASP.NET Core 2.1 專案 (或更新版本) 時,Visual Studio 會偵測開發憑證是否遺失,且將提供安裝並信任該憑證。
注意
ASP.NET Core HTTPS 開發憑證是自我簽署的。
如需在電腦上啟用本機 HTTPS 的詳細資訊,請參閱啟用本機 HTTPS。
指定本機電腦位址
在 .NET MAUI 應用程式中定義本機 Web 服務的 URL 的程式代碼中,請確定 Web 服務 URL 指定 HTTPS 配置,以及正確的主機名。 類別 DeviceInfo
可用來偵測應用程式執行的平臺。 接著可以設定正確的主機名,如下所示:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
如需 類別 DeviceInfo
的詳細資訊,請參閱 裝置資訊。
繞過憑證安全性檢查
嘗試從在 Android 模擬器中執行的 .NET MAUI 應用程式叫用本機安全 Web 服務會導致 java.security.cert.CertPathValidatorException
擲回,並出現訊息,指出找不到認證路徑的信任錨點。 同樣地,嘗試從 iOS 模擬器中執行的 .NET MAUI 應用程式叫用本機安全 Web 服務,將會產生 NSURLErrorDomain
錯誤,指出伺服器的憑證無效。 發生這些錯誤的原因是本機 HTTPS 開發憑證是自我簽署,而 Android 或 iOS 不會信任自我簽署憑證。 因此,當應用程式取用本機安全 Web 服務時,必須忽略 SSL 錯誤。
這可以藉由將已設定的原生 HttpMessageHandler
類別版本傳遞至 HttpClient
建構函式來完成,以指示 HttpClient
類別信任透過 HTTPS 的 localhost 通訊。 類別 HttpMessageHandler
是抽象類,其 Android 上的實作是由 AndroidMessageHandler
類別提供,而 iOS 上的 NSUrlSessionHandler
實作是由 類別提供。
下列範例顯示類別,其 AndroidMessageHandler
會在 Android 上設定 類別,以及 NSUrlSessionHandler
iOS 上的 類別,以信任透過 HTTPS 的 localhost 通訊:
public class HttpsClientHandlerService
{
public HttpMessageHandler GetPlatformMessageHandler()
{
#if ANDROID
var handler = new Xamarin.Android.Net.AndroidMessageHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert != null && cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
return handler;
#elif IOS
var handler = new NSUrlSessionHandler
{
TrustOverrideForUrl = IsHttpsLocalhost
};
return handler;
#else
throw new PlatformNotSupportedException("Only Android and iOS supported.");
#endif
}
#if IOS
public bool IsHttpsLocalhost(NSUrlSessionHandler sender, string url, Security.SecTrust trust)
{
if (url.StartsWith("https://localhost"))
return true;
return false;
}
#endif
}
在Android上 GetPlatformMessageHandler
,方法會傳 AndroidMessageHandler
回物件。 方法會將 GetPlatformMessageHandler
ServerCertificateCustomValidationCallback
物件上的 AndroidMessageHandler
屬性設定為回呼,這個回呼會忽略本機 HTTPS 開發憑證的憑證安全性檢查結果。
在 iOS 上 GetPlatformMessageHandler
,方法會 NSUrlSessionHandler
傳回 物件,該物件會將其 TrustOverrideForUrl
屬性設定為與 IsHttpsLocalHost
委派簽章相符的 NSUrlSessionHandler.NSUrlSessionHandlerTrustOverrideForUrlCallback
委派。 當 URL 以 開頭https://localhost
時,委派IsHttpsLocalHost
會true
傳回 。
然後,產生的 HttpClientHandler
物件可以當做自變數傳遞至偵錯組建的 HttpClient
建構函式:
#if DEBUG
HttpsClientHandlerService handler = new HttpsClientHandlerService();
HttpClient client = new HttpClient(handler.GetPlatformMessageHandler());
#else
client = new HttpClient();
#endif
在 Android 模擬器或 iOS 模擬器中執行的 .NET MAUI 應用程式,接著可以使用透過 HTTPS 在本機執行的 ASP.NET Core Web 服務。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應