0

Im trying to connect to an API and get the data from the "User" table so that the credentials can be authenticated. However after executing GetAsync() the app stucks in a deadlock and doesnt do anything. I have tested the API with postman and it works.

public async Task<User> UserCredentialsGet(string name, string password)
    {
        var user = new User();
        HttpClient client = new HttpClient();

        string url = "https://xxx.xxx.xxx.xxx:xxxx/api/Users/username=" + name + "/" + "password=" + password ;
        Uri uri = new Uri(url);
        try
        {
            var response = await client.GetAsync(uri).ConfigureAwait(false);

            if (response.IsSuccessStatusCode)
            {
                string content = response.Content.ReadAsStringAsync().Result;
                user = JsonConvert.DeserializeObject<User>(content);
            }
        }
        catch (Exception ex)
        {
            
        }

        return user;
        //return await Task.FromResult(user);
    }
michchou
  • 5
  • 4
  • is it actually deadlocked, or is it just hung? Are you your request is completing? Have you tried without using `ConfigureAwait`? – Jason Feb 07 '22 at 20:26
  • 3
    Why are you not using await here? `response.Content.ReadAsStringAsync().Result` You should almost 100% always avoid using `.Result` as it can lead to deadlocks. You should use `await response.Content.ReadAsStringAsync()` instead. – Kirk Woll Feb 07 '22 at 20:41
  • +1 for Kirks comment. Also because you said your code hangs on the `GetAsync()` call, try specifying the client timeout manually to a lower value to see if you really get an answer from the API and it isn't just a timeout (default is 100 seconds). Example: `client.Timeout = TimeSpan.FromSeconds(5);` – Danny Boy Feb 07 '22 at 21:00
  • Yes I have tried without `ConfigureAwait` but nothing happens. I have also tried without `.ReadAsStringAsync().Result` but again the result is the same. The problem is in `var response = await client.GetAsync(uri).ConfigureAwait(false);` line anyway. – michchou Feb 08 '22 at 08:23
  • @DannyBoy i used timeout but what changed is that now i get the error message _System.OperationCanceledException: 'The operation was canceled.'_ a lot faster. – michchou Feb 08 '22 at 08:27
  • have you tested connectivity from your device's browser? – Jason Feb 08 '22 at 16:06
  • @Jason Yes the api works fine. I tested it from both the PC's browser and my phone's. – michchou Feb 09 '22 at 11:29
  • Have you tested the exact URI that the httpClient calls though? There might be a difference between the one you called and the httpClient. `string url = "https://xxx.xxx.xxx.xxx:xxxx/api/Users/username=" + name + "/" + "password=" + password ; Uri uri = new Uri(url);` – Danny Boy Feb 10 '22 at 10:48
  • @DannyBoy I checked the url value by adding a breakpoint and it is the same address I use with postman and browser. – michchou Feb 10 '22 at 11:40
  • Hope this thread https://stackoverflow.com/questions/22157596/asp-net-web-api-operationcanceledexception-when-browser-cancels-the-request can give u some insights. – Alexandar May - MSFT Feb 24 '22 at 07:36

1 Answers1

0

GetAsync is Idisposable so try to use something like

    `using (HttpClient client = new HttpClient())
        {   
            using (HttpResponseMessage response = await client.GetAsync(uri, cancellationToken))
            {
                var stringResponse = await response.Content.ReadAsStringAsync();
                //todo process response
            }
        }
`

For me it works fine. Do not for forget await response

  • Thank you but it didnt work unfortunately. Its hanging at [using (HttpResponseMessage response = await client.GetAsync(uri, cancellationToken))]. After a while I get an error: System.OperationCanceledException: 'The operation was canceled.' – michchou Feb 08 '22 at 08:18
  • System.OperationCanceledException is fired by cancelation token or timeout. – Tomáš Zachoval Feb 08 '22 at 11:35
  • Are you sure that you are hiting a corect endpoint? Do you have correct url? something like `/username?=" + name` Maby missing questionmark – Tomáš Zachoval Feb 08 '22 at 11:41
  • I tried this with and without cancellation token. The api is running locally on debug mode and i changed the address from "localhost" to the internal ip. As I mentioned it runs well with postman and swagger so I cannot see a problem with the endpoint. – michchou Feb 09 '22 at 07:04
  • Ou sorry, i did not catch that, if your API is running on localhost you have to set a binding configuration in IISExpress in .vs\config\applicationhost.config something like this https://www.arkleseizure.net/accessing-a-local-net-website-api-from-a-xamarin-app – Tomáš Zachoval Feb 09 '22 at 08:03
  • I didnt find the file that was specified in the guide because i dont use IIS Express. However I edited the `applicationUrl` setting in `launchsettings.json` with zero results. I was hopeful for a moment when the guide mentioned that the android client cannot connect to the api while the connection settings are binded to localhost, but the miracle didnt happen... – michchou Feb 09 '22 at 11:22