從 iOS 模擬器和 Android 模擬器連線到本機 Web 服務
許多行動應用程式會使用 Web 服務。 開發階段中通常都會在本機部署 Web 服務,並透過在 iOS 模擬器或 Android 模擬器中執行的行動應用程式取用。 這樣就不需將 Web 服務部署至裝載的端點,而且能夠提供簡易的偵錯體驗,因為行動應用程式和 Web 服務都是在本機執行。
在 iOS 模擬器或 Android 模擬器中執行的行動應用程式,可以取用透過 HTTP 公開並在本機執行的 ASP.NET Core Web 服務,如下所示:
- 在 iOS 模擬器中執行的應用程式可以透過電腦的 IP 位址,或透過
localhost
主機名稱,連線到本機 HTTP Web 服務。 例如,提供一個透過/api/todoitems/
相對 URI 公開 GET 作業的本機 HTTP Web 服務,在 iOS 模擬器中執行的應用程式就可以透過傳送 GET 要求至http://localhost:<port>/api/todoitems/
來取用作業。 - 在 Android 模擬器中執行的應用程式可以透過
10.0.2.2
位址連線到本機 HTTP Web 服務,也就是您的主機回送介面 (在開發電腦上為127.0.0.1
) 的別名。 例如,提供一個透過/api/todoitems/
相對 URI 公開 GET 作業的本機 HTTP Web 服務,在 Android 模擬器中執行的應用程式就可以透過傳送 GET 要求至http://10.0.2.2:<port>/api/todoitems/
來取用作業。
但是,必須進行一些額外的工作,在 iOS 模擬器或 Android 模擬器中執行的應用程式才能取用透過 HTTPS 公開的本機 Web 服務。 針對此案例,流程如下:
- 在您的電腦上建立自我簽署開發憑證。 如需詳細資訊,請參閱建立開發憑證。
- 將項目設定為針對偵錯組建使用適當的
HttpClient
網路堆疊。 如需詳細資訊,請參閱設定專案。 - 指定本機電腦的位址。 如需詳細資訊,請參閱指定本機電腦位址。
- 繞過本機開發憑證安全性檢查。 如需詳細資訊,請參閱繞過憑證安全性檢查。
我們會輪流討論每個項目。
建立開發憑證
安裝 .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。
設定專案
在 iOS 和 Android 上執行的 Xamarin 應用程式可以指定 HttpClient
類別使用哪些網路堆疊,並提供使用受控網路堆疊,或使用原生網路堆疊的選項。 受控堆疊提供高層級相容性,具備現有 .NET 程式碼,但僅限於 TLS 1.0 且執行速度可能會比較慢,並產生較大的可執行檔大小。 原生堆疊速度可以更快並提供更高的安全性,但可能不會提供 HttpClient
類別的所有功能。
iOS
在 iOS 上執行的 Xamarin 應用程式可以使用受控網路堆疊,或使用原生 CFNetwork
或 NSUrlSession
網路堆疊。 根據預設,新的 iOS 平台專案使用 NSUrlSession
網路堆疊,以支援 TLS 1.2,並使用原生 API 以獲得更好的效能與較小的可執行檔大小。 如需詳細資訊,請參閱適用於 iOS/macOS 的 HttpClient 和 SSL/TLS 實作選取器。
Android
在 Android 上執行的 Xamarin 應用程式可以使用受控 HttpClient
網路堆疊,或原生 AndroidClientHandler
網路堆疊。 根據預設,新的 Android 平台專案使用 AndroidClientHandler
網路堆疊,以支援 TLS 1.2,並使用原生 API 以獲得更好的效能與較小的可執行檔大小。 如需 Android 網路堆疊的詳細資訊,請參閱 Android 的 HttpClient Stack 和 SSL/TLS 實作選取器。
指定本機電腦位址
iOS 模擬器和 Android 模擬器都能存取在您本機電腦上執行的安全 Web 服務。 但是每部電腦的本機電腦位址都不一樣。
iOS
iOS 模擬器會使用主機電腦網路。 因此,在模擬器中執行的應用程式可以透過電腦 IP 位址,或透過 localhost
主機名稱,連線到在您本機電腦上執行的 Web 服務。 例如,提供一個透過 /api/todoitems/
相對 URI 公開 GET 作業的本機安全 Web 服務,在 iOS 模擬器中執行的應用程式就可以透過傳送 GET 要求至 https://localhost:<port>/api/todoitems/
來使用作業。
注意
從 Windows 的 iOS 模擬器中執行行動應用程式時,應用程式會顯示在 Windows 的遠端 iOS 模擬器中。 但是應用程式是在配對的 Mac 上執行。 所以在 Mac 上執行的 iOS 應用程式並沒有 localhost 存取權,無法存取在 Windows 上執行的 Web 服務。
Android
Android 模擬器的每個執行個體都會與您的開發電腦網路介面隔離,並在虛擬路由器背後執行。 因此,模擬的裝置看不到您的開發電腦,或網路上的其他模擬器執行個體。
但是,每個模擬器的虛擬路由器都會管理一個特殊的網路空間,其中包括預先配置的位址,而 10.0.2.2
位址為您主機回送介面的別名 (在您的開發電腦上為 127.0.0.1)。 因此,提供一個透過 /api/todoitems/
相對 URI 公開 GET 作業的本機安全 Web 服務,在 Android 模擬器中執行的應用程式就可以透過傳送 GET 要求至 https://10.0.2.2:<port>/api/todoitems/
來取用作業。
偵測作業系統
DeviceInfo
類別可用於偵測應用程式執行所在的平台。 然後可以如下所示,設定適當的主機名稱 (讓您能夠存取本機安全 Web 服務):
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
的詳細資訊,請參閱 Xamarin.Essentials:裝置資訊。
繞過憑證安全性檢查
嘗試從在 iOS 模擬器或 Android 模擬器中執行的應用程式叫用本機安全 Web 服務時,將會擲回 HttpRequestException
,即使是在每個平台上使用受控網路堆疊也一樣。 這是因為本機 HTTPS 開發憑證是自我簽署的,而自我簽署憑證不受 iOS 或 Android 信任。 因此,應用程式在使用本機安全 Web 服務時,必須忽略 SSL 錯誤。 在 iOS 和 Android 上使用 Managed 和原生網路堆疊時,可以將 對象的 屬性HttpClientHandler
設定ServerCertificateCustomValidationCallback
為回呼,以忽略本機 HTTPS 開發憑證的憑證安全性檢查結果,即可達成此目的:
// This method must be in a class in a platform project, even if
// the HttpClient object is constructed in a shared project.
public HttpClientHandler GetInsecureHandler()
{
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
return handler;
}
在此程式碼範例中,當進行驗證的憑證不是 localhost
時,就會傳回伺服器憑證驗證結果。 對於此憑證來說,系統會忽略驗證結果並傳回 true
,指示憑證是否有效。 產生的 HttpClientHandler
物件應該以自變數的形式傳遞至偵錯組建的 HttpClient
建構函式:
#if DEBUG
HttpClientHandler insecureHandler = GetInsecureHandler();
HttpClient client = new HttpClient(insecureHandler);
#else
HttpClient client = new HttpClient();
#endif
啟用 HTTP 純文字流量
您可以選擇性地設定 iOS 和 Android 專案,以允許純文字 HTTP 流量。 如果後端服務設定為允許 HTTP 流量,您可以在基底 URL 中指定 HTTP,然後將專案設定為允許純文字流量:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
iOS ATS 退出宣告
若要在 iOS 上啟用純文字本機流量,您應該將下列內容新增至 Info.plist 檔案,以退出退出 ATS:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Android 網路安全性設定
若要在 Android 上啟用純文字本機流量,您應該在 Resources/xml 資料夾中新增名為 network_security_config.xml 的新 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>
然後,在 Android 指令清單中的應用程式節點上設定 networkSecurityConfig 屬性:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
請確定 [建置動作] 已設定為 AndroidResource,否則不會在建置階段找到 XML 檔案。