Conectar-se a serviços Web locais de emuladores do Android e simuladores do iOS
Muitos aplicativos móveis e de área de trabalho consomem serviços Web. Durante a fase de desenvolvimento de software, é comum implantar um serviço Web localmente e consumi-lo de um aplicativo em execução no emulador do Android ou simulador do iOS. Isso evita a necessidade de implantar o serviço Web em um ponto de extremidade hospedado e habilita uma experiência de depuração simples porque o aplicativo e o serviço Web estão sendo executados localmente.
Os aplicativos .NET Multi-Platform App UI (.NET MAUI) executados no Windows ou no MacCatalyst podem consumir serviços Web do ASP.NET Core executados localmente por HTTP ou HTTPS sem nenhum trabalho adicional, desde que você tenha confiança em seu certificado de desenvolvimento. No entanto, trabalho adicional é necessário quando o aplicativo está sendo executado no emulador Android ou simulador iOS, e o processo é diferente dependendo se o serviço Web está sendo executado sobre HTTP ou HTTPS.
Endereço do computador local
O emulador Android e o simulador iOS fornecem acesso aos serviços Web em execução por HTTP ou HTTPS em seu computador local. No entanto, o endereço do computador local é diferente para cada um deles.
Android
Cada instância do emulador do Android é isolada das interfaces de rede de seu computador de desenvolvimento e é executado atrás de um roteador virtual. Portanto, um dispositivo emulado não pode ver seu computador de desenvolvimento ou outras instâncias do emulador na rede.
No entanto, o roteador virtual para cada emulador gerencia um espaço de rede especial que inclui os endereços alocados previamente, sendo que o endereço 10.0.2.2
é um alias para a sua interface host de loopback (127.0.0.1 em seu computador de desenvolvimento). Portanto, considerando um serviço Web local que expõe uma operação GET por meio do URI relativo /api/todoitems/
, o aplicativo em execução no emulador do Android pode consumir a operação enviando uma solicitação GET ao http://10.0.2.2:<port>/api/todoitems/
ou https://10.0.2.2:<port>/api/todoitems/
.
iOS
O simulador do iOS usa a rede do computador host. Portanto, os aplicativos em execução no simulador podem se conectar aos serviços Web em execução no computador local por meio do endereço IP dos computadores ou por meio do nome do host localhost
. Por exemplo, considerando um serviço Web local que expõe uma operação GET por meio do URI relativo /api/todoitems/
, o aplicativo em execução no simulador do iOS pode consumir a operação enviando uma solicitação GET ao http://localhost:<port>/api/todoitems/
ou https://localhost:<port>/api/todoitems/
.
Observação
Ao executar um aplicativo .NET MAUI no simulador do iOS do Windows, o aplicativo é exibido no simulador do iOS remoto para Windows. No entanto, o aplicativo está em execução no Mac emparelhado. Portanto, não há acesso localhost a um serviço Web em execução no Windows para um aplicativo iOS em execução em um Mac.
Serviços Web locais em execução via HTTP
Um aplicativo MAUI do .NET em execução no emulador do Android ou simulador do iOS pode consumir um serviço Web do ASP.NET Core em execução localmente por HTTP. Isso pode ser feito configurando seu projeto de aplicativo .NET MAUI e seu projeto de serviço Web ASP.NET Core para permitir tráfego HTTP de texto não criptografado.
No código que define a URL do serviço Web local no aplicativo .NET MAUI, verifique se a URL do serviço Web especifica o esquema HTTP e o nome de host correto. A classe DeviceInfo pode ser usada para detectar a plataforma em que o aplicativo está sendo executado. O nome de host correto pode então ser definido da seguinte maneira:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Para obter mais informações sobre a classe DeviceInfo, consulte Informações do dispositivo.
Além disso, para executar seu aplicativo no Android, você deve adicionar a configuração de rede necessária e, para executar seu aplicativo no iOS, você deve recusar o ATS (Apple Transport Security). Para obter mais informações, consulte configuração de rede do Android e configuração do ATS do iOS.
Você também deve garantir que seu serviço Web do ASP.NET Core esteja configurado para permitir tráfego HTTP. Isso pode ser obtido adicionando um perfil HTTP à profiles
seção de launchSettings.json em seu projeto de serviço Web ASP.NET Core:
{
...
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "api/todoitems",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
...
}
}
Um aplicativo .NET Maui em execução no emulador do Android ou no simulador do iOS pode consumir um serviço Web do ASP.NET Core executado localmente por HTTP, desde que o serviço Web seja iniciado com o perfil http
.
Configuração de rede do Android
Há duas abordagens principais para habilitar o tráfego local de texto limpo no Android:
- Habilite o tráfego de rede de texto limpo para comunicação com todos os domínios. Para obter mais informações, consulte Habilitar o tráfego de rede de texto claro para todos os domínios.
- Habilite o tráfego de rede de texto limpo para comunicação com o domínio
localhost
. Para obter mais informações, consulte Habilitar o tráfego de rede de texto claro para o domínio localhost.
Habilitar o tráfego de rede de texto limpo para todos os domínios
O tráfego de rede de texto limpo para todos os domínios pode ser habilitado definindo a propriedade UsesCleartextTraffic
do atributo Application
como true
. Isso deve ser executado no arquivo Plataformas > Android > MainApplication.cs em seu projeto de aplicativo .NET MAUI e deve ser encapsulado em um #if DEBUG
para garantir que ele não esteja habilitado acidentalmente em um aplicativo de produção:
#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();
}
Observação
A propriedade UsesCleartextTraffic
é ignorada no Android 7.0 (API 24) e superior se um arquivo de configuração de segurança de rede estiver presente.
Habilitar o tráfego de rede de texto limpo para o domínio localhost
O tráfego de rede de texto limpo para o domínio localhost
pode ser habilitado criando um arquivo de configuração de segurança de rede. Isso pode ser obtido adicionando um novo arquivo XML chamado network_security_config.xml à pasta Platforms\Android\Resources\xml em seu projeto de aplicativo .NET MAUI. O arquivo XML deve especificar a seguinte configuração:
<?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>
Observação
Verifique se a ação de compilação do arquivo network_security_config.xml está definida como AndroidResource.
Em seguida, configure a propriedade networkSecurityConfig no nó do aplicativo no arquivo Platforms\Android\AndroidManifest.xml em seu projeto de aplicativo .NET MAUI:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config" ...>
...
</application>
</manifest>
Para obter mais informações sobre arquivos de configuração de segurança de rede, consulte Configuração de segurança de rede em developer.android.com.
Configuração do ATS do iOS
Para habilitar o tráfego local de texto não criptografado no iOS, você deve desativar o Apple Transport Security (ATS) em seu aplicativo .NET MAUI. Isso pode ser obtido adicionando a seguinte configuração ao arquivo Platforms\iOS\Info.plist em seu projeto de aplicativo .NET MAUI:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Para obter mais informações sobre o ATS, consulte Impedindo conexões de rede inseguras em developer.apple.com.
Serviços Web locais em execução via HTTPS
Um aplicativo MAUI do .NET em execução no emulador do Android ou simulador do iOS pode consumir um serviço Web do ASP.NET Core em execução localmente por HTTPS. O processo para habilitar isso é o feito da seguinte forma:
- Confie no certificado de desenvolvimento autoassinado em seu computador. Para obter mais informações, consulte Confiar em seu certificado de desenvolvimento.
- Especifique o endereço do computador local. Para saber mais, confira as informações sobre como especificar o endereço do computador local.
- Ignore a verificação de segurança do certificado de desenvolvimento local. Para saber mais, veja Ignorar a verificação de segurança do certificado.
Cada item será apresentado separadamente.
Confie no seu certificado de desenvolvimento
A instalação do SDK do .NET Core instala o certificado de desenvolvimento HTTPS do ASP.NET Core no repositório de certificados do usuário local. No entanto, embora o certificado tenha sido instalado, ele não é confiável. Para confiar no certificado, realize a única etapa a seguir para executar a ferramenta do dotnet dev-certs
:
dotnet dev-certs https --trust
O comando a seguir fornece ajuda para a ferramenta dev-certs
:
dotnet dev-certs https --help
Como alternativa, quando você executa um projeto do ASP.NET Core 2.1 (ou superior), que usa HTTPS, o Visual Studio detectará se o certificado de desenvolvimento está ausente e oferecerá a possibilidade de instalá-lo e de confiar nele.
Observação
O certificado de desenvolvimento HTTPS do ASP.NET Core é autoassinado.
Para saber mais sobre como habilitar o HTTPS local em seu computador, confira o artigo Habilitar o HTTPS local.
Especificar o endereço do computador local
No código que define a URL do serviço Web local no aplicativo .NET MAUI, verifique se a URL do serviço Web especifica o esquema HTTPS e o nome de host correto. A classe DeviceInfo pode ser usada para detectar a plataforma em que o aplicativo está sendo executado. O nome de host correto pode então ser definido da seguinte maneira:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Para obter mais informações sobre a classe DeviceInfo, consulte Informações do dispositivo.
Ignorar a verificação de segurança do certificado
A tentativa de invocar um serviço Web seguro local de um aplicativo .NET MAUI em execução em um emulador Android resultará em um lançamento contínuo de java.security.cert.CertPathValidatorException
, com uma mensagem indicando que a âncora de confiança para o caminho de certificação não foi encontrada. Da mesma forma, a tentativa de invocar um serviço Web seguro local de um aplicativo .NET MAUI em execução em um simulador iOS resultará em um erro NSURLErrorDomain
com uma mensagem indicando que o certificado do servidor é inválido. Esses erros ocorrem porque o certificado de desenvolvimento HTTPS local é autoassinado, e os certificados autoassinados não são confiáveis pelo Android ou iOS. Portanto, é necessário ignorar erros de SSL quando um aplicativo consome um serviço Web seguro local.
Isso pode ser feito configurando uma instância de HttpClientHandler com um ServerCertificateCustomValidationCallback personalizado, que instrui a classe HttpClient a confiar na comunicação localhost em HTTPS. O exemplo a seguir mostra como criar uma instância de HttpClientHandler que ignorará os erros de validação de certificado 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
O código acima ignora erros de validação de certificado localhost, mas apenas em builds de depuração. Essa abordagem evita incidentes de segurança em builds de produção.
Um aplicativo .NET MAUI em execução no emulador do Android ou simulador do iOS pode, então, consumir um serviço Web do ASP.NET Core em execução localmente por HTTPS.