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.
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.