Condividi tramite


Connettersi ai servizi Web locali da emulatori Android e simulatori iOS

Browse sample.Sfogliare l'esempio. Esplorare l'esempio

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.

Suggerimento

Se si usa .NET 10 o versione successiva, è consigliabile usare l'integrazione Aspira per semplificare la connessione ai servizi Web locali. Aspirare gestisce automaticamente la configurazione di rete specifica della piattaforma, l'individuazione dei servizi e i tunnel di sviluppo, eliminando gran parte della configurazione manuale descritta in questo articolo.

Le app .NET Multi-platform App UI (.NET MAUI) che vengono eseguite su Windows o MacCatalyst possono consumare servizi web ASP.NET Core che sono in esecuzione localmente su HTTP o HTTPS senza ulteriori operazioni, a condizione che tu abbia considerato attendibile il tuo 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 della macchina 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 come alias per l'interfaccia di loopback dell'host (127.0.0.1 sul computer di sviluppo). Pertanto, dato un servizio web locale che espone un'operazione GET tramite il relativo URI /api/todoitems/, 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 sul computer locale tramite l'indirizzo IP del computer o tramite il nome host localhost. 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 remote iOS simulator for 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 classe DeviceInfo può essere usata per rilevare la piattaforma su cui è in esecuzione l'applicazione. 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 ulteriori informazioni sulla classe DeviceInfo, 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 ulteriori informazioni, vedere Configurazione di rete Android e Configurazione ATS di iOS.

È 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 sezione profiles 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 tutti i domini

Il traffico di rete non crittografato per tutti i domini può essere abilitato impostando la proprietà UsesCleartextTraffic dell'attributo Application su true. Questa operazione deve essere eseguita nel file Platforms > Android > MainApplication.cs nel progetto di app .NET MAUI, e deve essere racchiusa in un #if DEBUG per assicurarsi che non sia abilitata 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 proprietà UsesCleartextTraffic 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 dominio localhost 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 sul nodo applicazione nel file Platforms\Android\AndroidManifest.xml nel progetto di app .NET MAUI.

<?xml version="1.0" encoding="utf-8"?>
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config" ...>
        ...
    </application>
</manifest>

Per ulteriori informazioni sui file di configurazione della sicurezza di rete, consultare Configurazione della sicurezza di rete su 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 ulteriori informazioni su ATS, vedere Prevenzione delle connessioni di rete non sicure su 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:

  1. Fidati del certificato di sviluppo autofirmato sul tuo computer. Per ulteriori informazioni, consulta Fidati del tuo certificato di sviluppo.
  2. Specificare l'indirizzo del computer locale. Per ulteriori informazioni, consultare Specificare l'indirizzo del computer locale.
  3. Evitare il controllo di sicurezza del certificato di sviluppo locale. Per ulteriori informazioni, vedere Eludere il controllo della 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, eseguire una sola volta il seguente passaggio per eseguire lo strumento dotnet dev-certs:

dotnet dev-certs https --trust

Il comando seguente fornisce aiuto 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 classe DeviceInfo può essere usata per rilevare la piattaforma su cui è in esecuzione l'applicazione. 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 ulteriori informazioni sulla classe DeviceInfo, vedere Informazioni sul dispositivo.

Evitare il controllo di sicurezza del certificato

Se tenti di richiamare un servizio Web protetto locale da un'app .NET MAUI in esecuzione su un emulatore Android, verrà lanciata un'eccezione con un 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'applicazione .NET MAUI in esecuzione in un simulatore iOS genererà un errore NSURLErrorDomain 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 HttpClientHandler che ignorerà gli errori di convalida del certificato per 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.