Usare le funzionalità di rete specifiche della piattaforma

HttpClient è un'implementazione gestita e quindi indipendente dallo stack di rete della piattaforma nativa. Di conseguenza, HttpClient non può usare le funzionalità di rete native di ogni piattaforma, che risulta perciò poco efficiente e meno ottimizzata.

In questa unità si sfrutta l'estendibilità di HttpClient e si aggiunge il supporto per lo stack di rete della piattaforma nativa.

Problemi con HttpClient

Per impostazione predefinita, HttpClient usa uno stack di rete gestito basato su interfacce di sistema operativo di livello base. Per questo motivo, HttpClient è indipendente dagli stack di rete in ogni piattaforma. Android e iOS hanno entrambi stack di rete nativi più efficienti, ma hanno anche API univoche che ne rendono più difficile l'uso da C#.

Di conseguenza, HttpClient non usa completamente la piattaforma nativa. Lo stack di rete nativo, ad esempio, quando la rete dati è disattivata, prova ad abilitarla automaticamente. Poiché HttpClient non usa lo stack di rete nativo per impostazione predefinita, non proverà ad attivarla.

Che cos'è un gestore di messaggi?

HttpClient è progettato per essere estendibile e supporta i gestori di messaggi per determinare la modalità di trasferimento delle informazioni e di gestione degli scenari HTTP comuni. Microsoft, ad esempio, ha creato un gestore di messaggi denominato HttpClientHandler. È possibile usarlo per personalizzare alcune funzionalità di HttpClient. Di seguito è riportato un esempio che mostra l'uso di HttpClientHandler:

var handler = new HttpClientHandler() {
   AllowAutoRedirect = false,
   UseProxy = true,
   AutomaticDecompression = DecompressionMethods.GZip,
   Credentials = new NetworkCredential("user", "passwd")
};

var client = new HttpClient(handler);

Come si può osservare, HttpClientHandler ha proprietà che è possibile impostare per personalizzare il comportamento di HttpClient. Per applicare le personalizzazioni a HttpClient, passarle nel costruttore.

Che cos'è NSUrlSessionHandler?

Xamarin.iOS include un gestore di messaggi denominato NSUrlSessionHandler, che fa in modo che HttpClient usi lo stack di rete nativo. NSUrlSessionHandler offre vantaggi come:

  • Attivazione automatica dell'opzione prima di avviare una richiesta.
  • Utilizzo del pool di connessioni iOS.
  • Uso di code di invio invece che di thread gestiti.

Il gestore permette a HttpClient di funzionare come un'applicazione nativa quando gestisce la rete.

Per impostare NSUrlSessionHandler, il codice è simile a quello dell'esempio seguente:

var client = new HttpClient(new NSUrlSessionHandler());

HttpClient ha ora i vantaggi dello stack di rete nativo.

Che cos'è AndroidClientHandler?

Proprio come Xamarin.iOS, Xamarin.Android include un gestore di messaggi chiamato AndroidClientHandler. AndroidClientHandler trasferisce l'attività di comunicazione di rete allo stack UrlConnection di Android. Questo gestore consente a HttpClient di usare qualsiasi protocollo di rete e i protocolli di crittografia che Android è in grado di gestire, ad esempio TLS 1.2.

Per impostare AndroidClientHandler, il codice è simile a quello dell'esempio seguente:

var client = new HttpClient(new AndroidClientHandler());

Quando usare NSUrlSessionHandler e AndroidClientHandler

Come regola generale, usare sempre NSUrlSessionHandler e AndroidClientHandler con HttpClient. Entrambi offrono i vantaggi dello stack di rete nativo.

Questi gestori vengono usati per impostazione predefinita nei nuovi progetti Xamarin.Forms. Esistono impostazioni del progetto per modificare il valore HttpClient predefinito.

Per modificare il gestore HttpClient predefinito per Xamarin.iOS, aprire le proprietà del progetto iOS. Nella scheda Compilazione iOS è disponibile l'opzione Implementazione di HttpClient. Se questa opzione viene impostata su NSUrlSession, HttpClient usa il gestore nativo per iOS senza passarlo al costruttore.

Per modificare il gestore HttpClient predefinito per Xamarin.Android, aprire le proprietà del progetto Android. Nella scheda Opzioni Android fare clic sul pulsante Avanzate in basso. Nella finestra di dialogo Opzioni Android avanzate è disponibile l'opzione Implementazione di SSL/TLS. Impostando questo valore su Native TLS 1.2+, HttpClient userà il gestore di messaggi predefinito.

Che cos'è App Transport Security?

Prima di concludere questa unità, c'è un'altra cosa da tenere presente quando si usa lo stack di rete nativo in iOS. App Transport Security è una funzionalità che richiede che ogni comunicazione di rete eseguita attraverso lo stack di rete nativo usi TLS 1.2 o versione successiva. Gli algoritmi di crittografia moderni impediranno la divulgazione delle informazioni qualora una delle chiavi a lungo termine fosse compromessa.

Se l'app non osserva queste regole, le viene negato l'accesso alla rete. Se l'applicazione presenta questo problema, sono disponibili due opzioni. In primo luogo, è possibile modificare l'endpoint in modo che soddisfi i criteri di App Transport Security. In secondo luogo, è possibile rifiutare esplicitamente App Transport Security impostando alcune chiavi nel file Info.plist.

Rifiutare esplicitamente App Transport Security

Per rifiutare esplicitamente App Transport Security, aggiungere al file Info.plist una nuova chiave denominata NSAppTransportSecurity. In tale dizionario aggiungere un'altra chiave denominata NSExceptionDomains, che contiene un elemento figlio per ognuno degli endpoint di destinazione. Ecco un esempio di codice da aggiungere per rifiutare esplicitamente un endpoint:

<key>NSAppTransportSecurity</key>
<dict>
   <key>NSExceptionDomains</key>
      <dict>
      <key>xam150.azurewebsites.net</key>
      <dict>
         <!-- specific options here -->
      </dict>
   </dict>
</dict>

In questo esempio è stata aggiunta all'endpoint un'eccezione in xam150.azurewebsites.net. Sono disponibili opzioni che è possibile aggiungere per essere più specifici sulla modalità di rifiuto esplicito. Queste indicazioni non rientrano nell'ambito del modulo. Le opzioni sono documentate nel sito Web di Apple.

Se infine non è possibile identificare tutti gli endpoint, disabilitare App Transport Security per tutti gli endpoint non specificati usando la chiave NSAllowsArbitraryLoads. Ecco un esempio nel codice:

<key>NSAppTransportSecurity</key>
<dict>
   <key>NSAllowsArbitraryLoads</key>
   <true/>
</dict>

Verificare le conoscenze

1.

Quale dei seguenti è il motivo migliore per usare gli stack di rete nativi con HttpClient?

2.

Quale delle seguenti opzioni non è un modo valido per rifiutare esplicitamente App Transport Security?