Consuming REST service not working-the authentication or decryption has failed. Permissions needed?

robs23robs23 Member ✭✭

Hi Guys,

I'm trying to consume simple GET API service. Unfortunately, the code throws "The authentication or decryption has failed" at var response = await client.GetStringAsync(url);. I guess it might be caused by missing permission. How to grant them/make sure they are granted?

Here's my code:

private async void ReloadUsers()
    {
        using (var client = new HttpClient())
        {
            string url = "https://jsonplaceholder.typicode.com/posts";
            try
            {
                var response = await client.GetStringAsync(url);
                Users = JsonConvert.DeserializeObject<List<User>>(response);
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
    }

Best Answer

  • AlessandroCaliaroAlessandroCaliaro IT ✭✭✭✭✭
    Accepted Answer

    The problem is not in my code, but how you call the request

    try with this

            string output = "";
    
            Task.Run(async () => { output = await ds.ReloadUsers(); });
    
    
            b.Clicked += async (sender, e) =>
            {
                await Application.Current.MainPage.Navigation.PushAsync(new ScanPage(output));
            };
    

Answers

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    I use this code. It works for me

        public async Task<String> TestAsync()
        {
            HttpClient httpClient = new HttpClient(new NativeMessageHandler() { Timeout = new TimeSpan(0, 0, TIMEOUT), EnableUntrustedCertificates = true, DisableCaching = true });
    
            var request = new HttpRequestMessage(HttpMethod.Get, TEST);
            return await readStream( await httpClient.SendAsync(request));
        }
    
        async Task<String> readStream(HttpResponseMessage response)
        {
            if (response.IsSuccessStatusCode)
            {
                using (var stream = await response.Content.ReadAsStreamAsync())
                using (var reader = new StreamReader(stream))
                {
                    string text = reader.ReadToEnd();
                    Debug.WriteLine("RECEIVED: " + text);
                    return text;
    
                }
            }
    
            return null;
        }
    

    TEST is your url

    I use ModernHttpClient

  • robs23robs23 Member ✭✭
    @AlessandroCaliaro thank you for the answer.

    I'm trying your solution, but of course already encountered some issues:)

    1. I installed ModernHttpClient from NuGet (it's version 2.4.2 by Paul Betts), but its constructor doesn't accept "Timeout = new TimeSpan(0, 0, TIMEOUT), EnableUntrustedCertificates = true, DisableCaching = true". I checked and my ModernHttpClient had overloads like below:

    public NativeMessageHandler();
    public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification, NativeCookieHandler cookieHandler = null);

    I removed constructor's parameters then and went with:
    HttpClient httpClient = new HttpClient(new NativeMessageHandler());

    It rebuil ok, but when running I'm getting error at this line saying: HttpClient Not found (MissingMeth..). Any clue what's wrong?

    Robert
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    try with this

  • robs23robs23 Member ✭✭

    Thanks. Surprisingly it found only v.2.6.0 for me but I don't think it's much of a difference. I've added it to projects, rebuilt (correctly) and tried to test it - Unforuntely at the line I'm still getting error saying:

    System.MissingMethodException: Constructor on type 'System.Net.Http.HttpClient' not found.

  • seanydaseanyda GBMember ✭✭✭✭✭

    @robs23 said:
    Thanks. Surprisingly it found only v.2.6.0 for me but I don't think it's much of a difference. I've added it to projects, rebuilt (correctly) and tried to test it - Unforuntely at the line I'm still getting error saying:

    System.MissingMethodException: Constructor on type 'System.Net.Http.HttpClient' not found.

    ModernHttpClient will give you access to NativeMessageHandler() class. You still will need to install the System.Net.Http package.

  • robs23robs23 Member ✭✭

    Thanks seanyda. Well, I thought System.Net.Http is standard package that doesn't need to be installed.. Eitherway, I installed it from NuGet, rebuilt, tested - same error. Then I found other post in this forum saying solution was to to add the Microsoft.Bcl.Build package to all 3 projects (Forms, droid & iOs) and later to add Microsoft.Net.Http to all 3 projects. I did that, rebuilt, retested (probably hundredth time today) - same error at the very same line. How hard can it be to do such a simple thing in Xamarin..? Any other ideas I could possibly test, Guys?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Post your full test prj...

  • robs23robs23 Member ✭✭

    Here it is. When the app starts, it initializes dataService.cs (in "Classes" folder). Then dataService's method "ReloadUsers()" is called and there it breaks on:
    HttpClient httpClient = new HttpClient(new NativeMessageHandler() { Timeout = new TimeSpan(0, 0, 20), EnableUntrustedCertificates = true, DisableCaching = true });

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭
    Accepted Answer

    The problem is not in my code, but how you call the request

    try with this

            string output = "";
    
            Task.Run(async () => { output = await ds.ReloadUsers(); });
    
    
            b.Clicked += async (sender, e) =>
            {
                await Application.Current.MainPage.Navigation.PushAsync(new ScanPage(output));
            };
    
  • robs23robs23 Member ✭✭

    @AlessandroCaliaro Brilliant! I knew that my knowledge on asynchronous programming is none, but thought I could still build some simple app without it. As it turns out I must catch up on this fast! Big thank you for the effort!

    Robert

  • robs23robs23 Member ✭✭

    Just a quick one - assuming I would like to load downloaded data to List when it finished downloading, this should do the trick, right?

    Task.Run(async () => { output = await ds.ReloadUsers();
                    keeper.Users = JsonConvert.DeserializeObject<List<User>>(output);
                });
    

    Keeper looks as follows:

    public class UsersKeeper
        {
            public List<User> Users { get; set; }
    
        }
    

    And output is string as:

        [
            {
                "UserId": 4,
                "Name": "Krzysztof",
                "Surname": "Jeżyna",
                "Password": "jdepass123",
                "isMechanic": true,
                "TenantId": 1,
                "TenantName": "JDE_PL",
                "CreatedOn": "2018-04-18T07:00:00",
                "CreatedBy": 1,
                "CreatedByName": "Robert Roszak",
                "LastLoggedOn": null
            },
            {
                "UserId": 6,
                "Name": "Tomasz",
                "Surname": "Gorkowski",
                "Password": "jdepass123",
                "isMechanic": true,
                "TenantId": 1,
                "TenantName": "JDE_PL",
                "CreatedOn": "2018-04-20T11:06:47.413",
                "CreatedBy": 1,
                "CreatedByName": "Robert Roszak",
                "LastLoggedOn": null
            }
        ]
    

    I'm asking because (if the above is correct) keeper.Users.Count should read 2 whereas it reads 0

Sign In or Register to comment.