I am having trouble calling an ASP.NET core API from a Xamarin Android app. I am running the android app on an android emulator and I am running the API on my local machine. I have no trouble calling the api from my local machine so I know it works. I am also able to call other apis from Xamarin app. I am using the IP address 10.0.2.2 to route to my local machine. But I have not been able to successfully make any API calls to an API running from my local machine.
This is my MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="APICallerTest.MainPage">
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="API Caller Test" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
</Frame>
<StackLayout Padding="30,24,30,0">
<Button x:Name="CallAPIButton" VerticalOptions="Center" Text="Call API" Clicked="CallAPIButton_Clicked"/>
<Label x:Name="CalledLabel"></Label>
<Label x:Name="ResultLabel"></Label>
<Label x:Name="ErrorLabel"></Label>
<Label x:Name="StackTraceLabel"></Label>
</StackLayout>
</StackLayout>
</ContentPage>
This is my MainPage.xaml.cs:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace APICallerTest
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async Task CallAPI()
{
ResultLabel.Text = "";
ErrorLabel.Text = "";
StackTraceLabel.Text = "";
try
{
string uri = "http://10.0.2.2:57817/Weatherforecast";
HttpClient httpClient = new HttpClient();
HttpResponseMessage httpResponse = await httpClient.GetAsync(uri);
if (httpResponse.IsSuccessStatusCode)
{
string result = await httpResponse.Content.ReadAsStringAsync();
ResultLabel.Text = $"Result: {result}";
}
else
{
ResultLabel.Text = "Result: failed";
}
}
catch (Exception ex)
{
ErrorLabel.Text = $"Error Message: {ex.Message}";
StackTraceLabel.Text = $"Stack Trace: {ex.StackTrace}";
}
}
private void CallAPIButton_Clicked(object sender, EventArgs e)
{
CalledLabel.Text = "Called";
CallAPI();
}
}
}
This is what my api looks like on postman:
I was able to solve this issue thanks to this question: The SSL connection could not be established
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace APICallerTest
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async Task CallAPI()
{
ResultLabel.Text = "";
ErrorLabel.Text = "";
StackTraceLabel.Text = "";
try
{
string uri = "http://10.0.2.2:57817/Weatherforecast";
//++++++++++Added client handler here ++++++++++
HttpClientHandler clientHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
};
HttpClient httpClient = new HttpClient(clientHandler);
HttpResponseMessage httpResponse = await httpClient.GetAsync(uri);
if (httpResponse.IsSuccessStatusCode)
{
string result = await httpResponse.Content.ReadAsStringAsync();
ResultLabel.Text = $"Result: {result}";
}
else
{
ResultLabel.Text = "Result: failed";
}
}
catch (Exception ex)
{
ErrorLabel.Text = $"Error Message: {ex.Message}";
StackTraceLabel.Text = $"Stack Trace: {ex.StackTrace}";
}
}
private void CallAPIButton_Clicked(object sender, EventArgs e)
{
CalledLabel.Text = "Called";
CallAPI();
}
}
}
Although, a user pointed out that this does expose you to possible security risks. I think it should be fine for testing purposes.