Unable to call REST API with System.Net - what version of .Net works?

Hi all,

Inside my cross-platform application I am making a web API call to authenticate a Windows user., using the System.Net.Http namespace. The call never goes through; it never returns...seems like it reaches the server and just gets lost. It call works from all kinds of browsers, on a PC and on the Mac where I am developing the app from- I use System.Net.Http. To test, I adapted the "https://developer.xamarin.com/samples/xamarin-forms/WebServices/TodoREST/" example by making my call from within it to no avail.

On the Mac I created a Net Core 2.1 console app, executed the code and it ran successfully. The app uses packages Microsoft.NetCore.App 2.1.0, NetStandard.Library 2.0.3->Microsoft.NetCore.Platforms 2.1.0. With this information I went back to the cross-platform solution, updated the packages to match the console app's configuration, ran the app and the result is the same: call to the REST API never returns. I am at wits end.

My question is, what version of System.Net.Http must I use with cross-platform Xamarin applications? I am not able to see the list of all DLLs in the package as in times past...Bottom line is, in Visual Studio on either a PC or a Mac, the code executes as long as the solution is not a Xamarin Forms one.

Here is a snippet of my API call:

        static async Task<User> AuthenticateAsync(string credentials, string baseURI)
        {
            try
            {           
                _client.BaseAddress = new Uri(baseURI);

                _client.DefaultRequestHeaders.Accept.Clear();
                _client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = await _client.GetAsync($"api/principal/{credentials}");

                if (response.IsSuccessStatusCode)
                {
                    using (Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    {
                        using (var reader = new StreamReader(stream))
                        {
                           return JsonConvert.DeserializeObject<User>(Encryption.DecryptHex(JsonConvert.DeserializeObject<string>(reader.ReadToEnd()))); 
                        }
                    }
                }

                User user = new User(String.Empty, "*****");
                user.RequestResponseReasonPhrase = response.ReasonPhrase;
                return user;
            }
            catch 
            {
                //Do something?
                return null;
            }
        }

Thanks for your help!

Best Answer

Answers

  • tmoytmoy Member ✭✭

    @BillyLiu
    Thanks for taking the time to help. The problem is the call gets lost! By that I mean, it does not return...so no it never reaches the if (response.IsSuccessStatusCode) line and there is no exception thrown.
    I am even using Wireshark on the server to capture traffic on the endpoint, filtered by the port: the call just does not reach the endpoint from the Xamarin solution, it does from the Console application. This is weird.

    Right now I am going to create a library project within the Xamarin solution using the same code from the Console app that works. I will then reference the DLL to make the API call and see if it makes a difference and report my findings...

  • tmoytmoy Member ✭✭

    I resorted to RestSharp because the problem with System.Net.Http is that there is is an incompatibility between the versions of the cross-platform project and the library project where I moved the call. One is .Net Standard 2.0 and the other one .Net Core 2.1.1. One has System.Runtime version 4.1.2.0 and the other one 4.2.1.0.

    My RestSharp solution looks like this:

    public static User AuthenticateRSAsync(string credentials, string baseURI)
            {
                //http://pawel.sawicz.eu/async-and-restsharp/ http://www.hackered.co.uk/articles/restsharp-and-the-factory-pattern-you-really-should
                try
                {   
                    RestClient client = new RestClient(baseURI);
                    //client.BaseUrl = new Uri(baseURI);
    
                    var request = new RestRequest($"api/principal/{credentials}");
                    request.RequestFormat = DataFormat.Json;
    
                    User user = new User();
                    var response = client.Execute(request);
                    if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        user = JsonConvert.DeserializeObject<User>(Encryption.DecryptHex(JsonConvert.DeserializeObject<string>(response.Content)));
                        return user;
                    }
    
                    user = new User(String.Empty, "*****");
                    //user.ReasonPhrase = response.ReasonPhrase;
                    return user;
    
        //var asyncHandler = client.ExecuteAsync<User>(request, response => {
    
                    //  if(string.IsNullOrWhiteSpace(response.Content) || response.StatusCode != System.Net.HttpStatusCode.OK) 
        //                {
        //                   user = new User(String.Empty, "*****");
        //                }   
        //                else
                    //  {
        //                   user = JsonConvert.DeserializeObject<User>(Encryption.DecryptHex(JsonConvert.DeserializeObject<string>(response.Content)));
        //                }
    
                    //});
                    //return user;
                }
                catch(Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.InnerException);
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    //Do something?
                    return null;
                }
            }
    

    for now.

    The problem I am having now is that I am not taking advantage of my login button click handler's async capability as the very confusing RestSharp has an ExecuteAsync method that cannot be awaited...Luckily the procedure is fast and the lag on the form is minimal but my next task is to find a way to make that call asynchronous.

    Thank you to those who took the time to read and feel free to make suggestions.

Sign In or Register to comment.