Search code examples
c#xamarinxamarin.formsxamarin.androidrefit

Can't connect to api endpoint from mobile app


I created a .NET Core web api endpoint where I can retrieve some images that I want to display in my mobile app. I tested the endpoint locally by navigating to that route and via postman and both are working fine (showing the proper response). However, when I try to hit the endpoint from mobile side, it doesn't work. I get this cryptic error:

System.Net.Http.HttpRequestException: Network subsystem is down

Here's more of the exception info:

System.Net.Http.HttpRequestException: Network subsystem is down ---> System.Net.Sockets.SocketException: Network subsystem is down
  at System.Net.Http.ConnectHelper.ConnectAsync (System.String host, System.Int32 port, System.Threading.CancellationToken cancellationToken) [0x000c8] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs:65

I'm not sure what I'm doing wrong on the mobile side. I know for postman to get it to show, I had to turn SSL certification setting off. Do I need to do something similar on the mobile side?

Here's how I'm trying to do the call to the endpoint. I'm using refit:

    public static class FetchMediaService
    {
        public static INevarroApi apiService;
        static string baseUrl = "https://localhost:5001";

        public static async Task<List<Uri>> CallImagesEndpoint()
        {
            apiService = RestService.For<INevarroApi>(baseUrl);
            var images = await apiService.GetImages();
            return images;
        }

    }

Where:

    public interface INevarroApi
    {
        [Get("/images")]
        Task<List<Uri>> GetImages();
    }

OnAppearing in my codebehind for one of my views:

        protected override async void OnAppearing()
        {
            DualScreenLayoutInfo.PropertyChanged += OnFormsWindowPropertyChanged;
            DualScreenInfo.Current.PropertyChanged += OnFormsWindowPropertyChanged;
            var images = await FetchMediaService.CallImagesEndpoint(); //Where the exception is thrown 

        }

What am I doing wrong above?

I'm testing this on Android 10 (API 29) emulator on Mac OSX and backend code is running locally using Visual Studio for Mac (backend is .NET Core 3.1 web api project).


Solution

  • If you are using IISExpress try to change your debug configuration.

    Change to http://localhost:[PORT] to http://127.0.0.1:[PORT]

    Then you should be able to access it in android with http://10.0.2.2:[PORT]

    Vs Settings

    For Kestrel

    Settings should be done via IHostBuilder in Program.cs as following:

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        return Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        // This should do it
                        webBuilder.UseUrls("http://127.0.0.1:5000");
                        webBuilder.UseStartup<Startup>();
                    });
    }