.netmaui

.NET Maui Android app not seeing local API


The problem

I am currently working on a .NET maui app and I am trying to make requests to a local API (with the RestSharp library) that is running on my computer.

Here is the code that talks to my API:

public static async Task<bool> Authenticate(string username, string password)
{
  Ping ping = new Ping();
  PingReply reply = ping.Send("google.com");

  string baseURL = Constants.MobileAPIURI;
  var client = new RestClient(baseURL);
  var request = new RestRequest("login", Method.Post);
  request.AddQueryParameter("username", username);
  request.AddQueryParameter("password", password);

  RestResponse response = client.Execute(request, Method.Post);

  if (response.StatusCode == System.Net.HttpStatusCode.OK)
  {
    var token = System.Text.Json.JsonSerializer.Deserialize<string>(response.Content);

    if (!string.IsNullOrEmpty(token))
    {
      await SecureStorage.SetAsync(Constants.AUTHTOKENVALUE, token);
      return true;
    }
  }

  return false;
}

Whenever the code is run, the ping reply has a timed-out status and the RestResponse has a "Connnection failure" error message. I am running my App through an Android Emulator made with the Android Device Manager included in Visual Studio 2022

What I have tried

I have tried changing the network settings of the Android VM, and manually setting the proxy. I have however returned to the default proxy settings as I have found that my API is accessible when I access it through chrome on the VM (I can see the swagger UI and use the endpoints)

I have changed the base URL from http to https. The url used is 10.0.2.2:port, I know the vm can access it as I can see my API from the browser.

I have added clear text traffic to my manifest.xaml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:usesCleartextTraffic="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
</manifest>

Where I am right now

I am currently stuck on this problem. Every result I find on the subject deals with connections to the VM, but I know this isn't the case, as I can access the API in the browser of the VM. Another lead might be the google.com ping that timed-out. Once again I have no problem accessing Google in the browser.


Solution

  • After some digging, I found that the app refuses the connection to my api due to self signed certificates. I needed to add a flag to accept the connection:

    public static RestClient GetMobileAPIClient()
        {
          HttpClientHandler 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
    
          HttpClient client = new HttpClient(handler);
          client.BaseAddress = new Uri(Constants.MobileAPIURI);
    
          return new RestClient(client);
        }
    

    As for the ping that never returned anything, I found out that a ping always times out in an Android VM, unless you call a java operation directly.