Connettersi ai servizi Web locali da emulatori Android e simulatori iOS
Molte app per dispositivi mobili e desktop usano servizi Web. Durante la fase di sviluppo software, è comune distribuire un servizio Web in locale e usarlo da un'app in esecuzione nell'emulatore Android o nel simulatore iOS. Ciò evita di dover distribuire il servizio Web in un endpoint ospitato e consente un'esperienza di debug semplice perché sia l'app che il servizio Web sono in esecuzione in locale.
Le app .NET multipiattaforma dell'interfaccia utente (.NET MAUI) eseguite in Windows o MacCatalyst possono usare ASP.NET Servizi Web Core in esecuzione localmente su HTTP o HTTPS senza ulteriori operazioni, purché sia stato considerato attendibile il certificato di sviluppo. Tuttavia, è necessario un lavoro aggiuntivo quando l'app è in esecuzione nell'emulatore Android o nel simulatore iOS e il processo è diverso a seconda che il servizio Web sia in esecuzione su HTTP o HTTPS.
Indirizzo computer locale
L'emulatore Android e il simulatore iOS forniscono entrambi l'accesso ai servizi Web in esecuzione su HTTP o HTTPS nel computer locale. Tuttavia, l'indirizzo del computer locale è diverso per ognuno.
Android
Ogni istanza dell'emulatore di Android è isolata dalle interfacce di rete del computer di sviluppo e viene eseguita dietro un router virtuale. Pertanto, un dispositivo emulato non può visualizzare il computer di sviluppo o altre istanze dell'emulatore in rete.
Tuttavia, il router virtuale per ogni emulatore gestisce uno spazio di rete speciale che include gli indirizzi già allocati, con l'indirizzo 10.0.2.2
usato come alias per l'interfaccia di loopback host (127.0.0.1 nel computer di sviluppo). Pertanto, dato un servizio Web locale che espone un'operazione GET tramite l'URI /api/todoitems/
relativo, un'app in esecuzione nell'emulatore Android può utilizzare l'operazione inviando una richiesta GET a http://10.0.2.2:<port>/api/todoitems/
o https://10.0.2.2:<port>/api/todoitems/
.
iOS
Il simulatore iOS usa la rete del computer host. Pertanto, le app in esecuzione nel simulatore possono connettersi ai servizi Web in esecuzione nel computer locale tramite l'indirizzo IP dei computer o tramite il localhost
nome host. Ad esempio, dato un servizio Web locale che espone un'operazione GET tramite l'URI /api/todoitems/
relativo, un'app in esecuzione nel simulatore iOS può utilizzare l'operazione inviando una richiesta GET a http://localhost:<port>/api/todoitems/
o https://localhost:<port>/api/todoitems/
.
Nota
Quando si esegue un'app .NET MAUI nel simulatore iOS da Windows, l'app viene visualizzata nel simulatore iOS remoto per Windows. Tuttavia, l'app è in esecuzione nel Mac associato. Di conseguenza, non esiste alcun accesso localhost a un servizio Web in esecuzione in Windows per un'app iOS in esecuzione in un Mac.
Servizi Web locali in esecuzione su HTTP
Un'app MAUI .NET in esecuzione nell'emulatore Android o nel simulatore iOS può usare un servizio Web ASP.NET Core in esecuzione localmente su HTTP. A tale scopo, è possibile configurare il progetto di app .NET MAUI e il progetto di servizio Web di ASP.NET Core per consentire il traffico HTTP non crittografato.
Nel codice che definisce l'URL del servizio Web locale nell'app MAUI .NET, assicurarsi che l'URL del servizio Web specifichi lo schema HTTP e il nome host corretto. La DeviceInfo classe può essere usata per rilevare la piattaforma in cui è in esecuzione l'app. Il nome host corretto può quindi essere impostato come segue:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Per altre informazioni sulla DeviceInfo classe, vedere Informazioni sul dispositivo.
Inoltre, per eseguire l'app in Android, è necessario aggiungere la configurazione di rete necessaria e per eseguire l'app in iOS è necessario rifiutare esplicitamente Apple Transport Security (ATS). Per altre informazioni, vedere Configurazione di rete Android e configurazione di iOS ATS.
È anche necessario assicurarsi che il servizio Web ASP.NET Core sia configurato per consentire il traffico HTTP. A tale scopo, è possibile aggiungere un profilo HTTP alla profiles
sezione di launchSettings.json nel progetto di servizio Web ASP.NET Core:
{
...
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "api/todoitems",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
...
}
}
Un'app MAUI .NET in esecuzione nell'emulatore Android o nel simulatore iOS può quindi usare un servizio Web ASP.NET Core in esecuzione in locale su HTTP, a condizione che il servizio Web venga avviato con il http
profilo.
Configurazione di rete Android
Esistono due approcci principali per abilitare il traffico locale di testo non crittografato in Android:
- Abilitare il traffico di rete non crittografato per la comunicazione con tutti i domini. Per altre informazioni, vedere Abilitare il traffico di rete non crittografato per tutti i domini.
- Abilitare il traffico di rete non crittografato per la comunicazione con il
localhost
dominio. Per altre informazioni, vedere Abilitare il traffico di rete non crittografato per il dominio localhost.
Abilitare il traffico di rete non crittografato per tutti i domini
Il traffico di rete non crittografato per tutti i domini può essere abilitato impostando la UsesCleartextTraffic
proprietà dell'attributo Application
su true
. Questa operazione deve essere eseguita nel file Platforms > Android > MainApplication.cs nel progetto di app MAUI .NET e deve essere sottoposto a wrapping in per #if DEBUG
assicurarsi che non sia abilitato accidentalmente in un'app di produzione:
#if DEBUG
[Application(UsesCleartextTraffic = true)]
#else
[Application]
#endif
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
Nota
La UsesCleartextTraffic
proprietà viene ignorata in Android 7.0 (API 24) e versioni successive se è presente un file di configurazione della sicurezza di rete.
Abilitare il traffico di rete non crittografato per il dominio localhost
Il traffico di rete non crittografato per il localhost
dominio può essere abilitato creando un file di configurazione della sicurezza di rete. A tale scopo, è possibile aggiungere un nuovo file XML denominato network_security_config.xml alla cartella Platforms\Android\Resources\xml nel progetto di app MAUI .NET. Il file XML deve specificare la configurazione seguente:
<?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>
Nota
Assicurarsi che l'azione di compilazione del file network_security_config.xml sia impostata su AndroidResource.
Configurare quindi la proprietà networkSecurityConfig nel nodo applicazione nel file Platforms\Android\AndroidManifest.xml nel progetto di app MAUI .NET:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config" ...>
...
</application>
</manifest>
Per altre informazioni sui file di configurazione della sicurezza di rete, vedere Configurazione della sicurezza di rete in developer.android.com.
Configurazione di iOS ATS
Per abilitare il traffico locale non crittografato in iOS, è necessario rifiutare esplicitamente Apple Transport Security (ATS) nell'app .NET MAUI. A tale scopo, aggiungere la configurazione seguente al file Platforms\iOS\Info.plist nel progetto di app MAUI .NET:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Per altre informazioni su ATS, vedere Prevenzione delle connessioni di rete non sicure in developer.apple.com.
Servizi Web locali in esecuzione su HTTPS
Un'app MAUI .NET in esecuzione nell'emulatore Android o nel simulatore iOS può usare un servizio Web ASP.NET Core in esecuzione in locale su HTTPS. Il processo per abilitare questa operazione è il seguente:
- Considerare attendibile il certificato di sviluppo autofirmato nel computer. Per altre informazioni, vedere Considerare attendibile il certificato di sviluppo.
- Specificare l'indirizzo del computer locale. Per altre informazioni, vedere Specificare l'indirizzo del computer locale.
- Evitare il controllo di sicurezza del certificato di sviluppo locale. Per altre informazioni, vedere Evitare il controllo di sicurezza del certificato.
Ogni elemento verrà presentato singolarmente.
Considerare attendibile il certificato di sviluppo
L'installazione di .NET Core SDK installa il certificato di sviluppo HTTPS di ASP.NET Core nell'archivio certificati utente locale. Tuttavia, anche se il certificato viene installato, non è attendibile. Per rendere attendibile il certificato, seguire questa procedura una sola volta per eseguire lo strumento dev-certs
dotnet:
dotnet dev-certs https --trust
Il comando seguente consente di visualizzare informazioni della Guida sullo strumento dev-certs
:
dotnet dev-certs https --help
In alternativa, quando si esegue un progetto ASP.NET Core 2.1 (o versione successiva), che usa HTTPS, Visual Studio rileva se il certificato di sviluppo è mancante e offre di installarlo e impostarlo come attendibile.
Nota
Il certificato di sviluppo HTTPS ASP.NET Core è autofirmato.
Per altre informazioni sull'abilitazione di HTTPS locale nel computer, vedere Abilitare HTTPS locale.
Specificare l'indirizzo del computer locale
Nel codice che definisce l'URL del servizio Web locale nell'app MAUI .NET, assicurarsi che l'URL del servizio Web specifichi lo schema HTTPS e il nome host corretto. La DeviceInfo classe può essere usata per rilevare la piattaforma in cui è in esecuzione l'app. Il nome host corretto può quindi essere impostato come segue:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Per altre informazioni sulla DeviceInfo classe, vedere Informazioni sul dispositivo.
Evitare il controllo di sicurezza del certificato
Se si tenta di richiamare un servizio Web protetto locale da un'app MAUI .NET in esecuzione in un emulatore Android, verrà generato un java.security.cert.CertPathValidatorException
messaggio che indica che l'ancoraggio di attendibilità per il percorso di certificazione non è stato trovato. Analogamente, il tentativo di richiamare un servizio Web protetto locale da un'app MAUI .NET in esecuzione in un simulatore iOS genererà un NSURLErrorDomain
errore con un messaggio che indica che il certificato per il server non è valido. Questi errori si verificano perché il certificato di sviluppo HTTPS locale è autofirmato e i certificati autofirmati non sono considerati attendibili da Android o iOS. Pertanto, è necessario ignorare gli errori SSL quando un'app utilizza un servizio Web protetto locale.
A tale scopo, è possibile configurare un'istanza di HttpClientHandler con un oggetto personalizzato ServerCertificateCustomValidationCallbackche indica alla classe di considerare attendibile la HttpClient comunicazione localhost tramite HTTPS. L'esempio seguente illustra come creare un'istanza di che ignorerà gli errori di convalida del HttpClientHandler certificato localhost:
var handler = new HttpClientHandler();
#if DEBUG
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert != null && cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
#endif
var client = new HttpClient(handler);
Importante
Il codice precedente ignora gli errori di convalida del certificato localhost, ma solo nelle compilazioni di debug. Questo approccio evita eventi imprevisti di sicurezza nelle build di produzione.
Un'app MAUI .NET in esecuzione nell'emulatore Android o nel simulatore iOS può quindi usare un servizio Web ASP.NET Core in esecuzione in locale tramite HTTPS.