Tomaltach
Tomaltach

Reputation: 923

Xamarin WebAPI call from PCL

I am trying to develop a Xamarin.Forms or Xamarin.iOS/Xamarin.Droid native app which can make a Web API call to my server. I get the error saying HttpRequestException thrown. Once I searched for a solution, it says that it is because it can't reach the socket, but I am unable to install it to a PCL project. So I check the solution for this and they said to use a proxy to reach the service.

Here is my problem. I have tried making a Proxy in the PCL to connect to a service in the .Droid or .iOS projects so they can use the sockets, (although I don't think the service should be in the app project itself because duplicate code). But the proxy class is not able to reference the the service because it is not in the project.

This is my RestService class.

public class RestService : IRestService
{
    private const string BASE_URI = "http://xxx.xxx.xxx.xxx/";
    private HttpClient Client;
    private string Controller;

    /**
     * Controller is the middle route, for example user or account etc.
     */
    public RestService(string controller)
    {
        Controller = controller;
        Client = new HttpClient();
    }

    /**
     * uri in this case is "userId?id=1".
     */
    public async Task<string> GET(string uri)
    {
        try
        {
            Client.BaseAddress = new Uri(BASE_URI);
            Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var fullUri = String.Format("api/{0}/{1}", Controller, uri);
            var response = Client.GetAsync(fullUri);
            string content = await response.Result.Content.ReadAsStringAsync();
            return content;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

I cannot find any good tutorials online on how to get this to work and any help in this regards would be much appreciated.

Upvotes: 2

Views: 420

Answers (1)

Nkosi
Nkosi

Reputation: 247018

You are mixing async/await and blocking calls .Result

public async Task<string> GET(string uri) {
    //...other code removed for brevity

    var response = Client.GetAsync(fullUri).Result;

    //...other code removed for brevity
}

which is causing a deadlock resulting in you not being able to get to socket.

When using async/await you need to go async all the way and avoid blocking calls like .Result and .Wait().

public async Task<string> GET(string uri) {
    try {
        Client.BaseAddress = new Uri(BASE_URI);
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var fullUri = String.Format("api/{0}/{1}", Controller, uri);
        var response = await Client.GetAsync(fullUri);
        var content = await response.Content.ReadAsStringAsync();
        return content;
    } catch (Exception e) {
        return null;
    }
}

Upvotes: 2

Related Questions