2

I used WebClient to download a file in my apk. But I got this error: Unhandled Exception:

System.Net.WebException: An exception occurred during a WebClient request.

And this is the code that I tried:

        {
            using (WebClient client = new WebClient())
            {
                
                    client.DownloadFile(
                        "https://code.org/images/social-media/code-2018-creativity.png",
                        @"j:\storage\emulated\legacy\Download\code-2018-creativity.png");
                
                
            }
        }   
Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44
DonAlex1897
  • 65
  • 1
  • 8

2 Answers2

1

Since you are only referring to a WebException, it may have to do with one of these cases:

  • The URI formed by combining BaseAddress and address is invalid.
  • The file or destination folder does not exist. Make sure your path to the destination folder already exists and that you have permissions to access it.
  • An error occurred while downloading data.

If you provide us more information about the exception we may be able to reduce the error to one of these cases. To get the InnerException you can do something like this:

{
  using (WebClient client = new WebClient ())
  {
    try
    {
      client.DownloadFile (
        "https://code.org/images/social-media/code-2018-creativity.png",
        @"j:\storage\emulated\legacy\Download\code-2018-creativity.png");
    }
    catch (Exception ex)
    {
      while (ex != null)
      {
        Console.WriteLine (ex.Message);
        ex = ex.InnerException;
      }
    }
  }
}
Diogo Rocha
  • 9,759
  • 4
  • 48
  • 52
  • I got this from console: 06-09 18:29:56.662 I/mono-stdout( 3959): An exception occurred during a WebClient request. Access to the path "/j:\storage\emulated\legacy\Download\code-2018-creativity.png" is denied. what should i do now? – DonAlex1897 Jun 09 '19 at 14:01
  • I changed the path to: @"j:\sdcard\code-2018-creativity.png" and added these permissions to manifest: but it didn't help. – DonAlex1897 Jun 09 '19 at 14:39
  • Have you got any idea @DiogoRocha? – DonAlex1897 Jun 10 '19 at 06:02
1

You have to ask permissions on run time even you have mentioned them in your manifest file if you are running Android api level 23 or greater.

Have a look at this blog would help about how to ask a run time permission:requesting-runtime-permissions-in-android

Also, this is the official sample of how to check RuntimePermissions

Refer: xamarin-system-unauthorizedaccessexception-access-to-the-path-is-denied

Update:

To ask run time permissions, you can use this plugin:Plugin.Permissions, install it to your project.

And then, call CheckMyPermissionAsync(); before you download the file:

private void FabOnClick(object sender, EventArgs eventArgs)
{
    View view = (View) sender;

    CheckMyPermissionAsync();
}

In the method CheckMyPermissionAsync(), check your Storage permission and then download file:

 public async void CheckMyPermissionAsync()
        {

            var permissionsStartList = new List<Permission>()
            {
                Permission.Storage
            };

            var permissionsNeededList = new List<Permission>();
            try
            {
                foreach (var permission in permissionsStartList)
                {
                    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
                    if (status != PermissionStatus.Granted)
                    {
                        permissionsNeededList.Add(permission);
                    }
                }
            }
            catch (Exception ex)
            {
            }

            var results = await CrossPermissions.Current.RequestPermissionsAsync(permissionsNeededList.ToArray());

            //Check the persimmison again
            var storeagePermission = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);

            if (storeagePermission == PermissionStatus.Granted)
            {
                //Download file here
                DownloadFile("http://www.dada-data.net/uploads/image/hausmann_abcd.jpg", "XF_Downloads");
            }
            else {

                Console.WriteLine("No permissions");
            }         
        }

You can check the result in the completed event:

private void Completed(object sender, AsyncCompletedEventArgs e)
{
    if (e.Error != null)
    {
        Console.WriteLine("success");
    }
    else
    {
        if (OnFileDownloaded != null) { }
        Console.WriteLine("fail");
    }
}

Note: pay attention to your filePath,make sure your path is correct, I use:

string pathToNewFolder = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, folder);

I updated my sample here: runtime-permission-xamarin.android

nevermore
  • 15,432
  • 1
  • 12
  • 30
  • I read links you refrenced but excuse me @JackHua, i didn't realy understand what should i do now. – DonAlex1897 Jun 10 '19 at 07:27
  • @mohamadaminkaviyani I will share a sample to you to tell you what you should do. I will update it later. – nevermore Jun 10 '19 at 07:30
  • thank you so much @JackHua. I just tested the app on my phone (the past results were taken from emulator) and it didn't launch even :| – DonAlex1897 Jun 10 '19 at 07:41
  • @mohamadaminkaviyani See my edited answer. Let me know if it works for you. – nevermore Jun 10 '19 at 08:25
  • Thank u so much @JackHua. The problem is solved, but i had an embarrassing mistake: @"j:\storage\emulated\legacy\Download\code-2018-creativity.png" The correct form is: @"j:/storage/emulated/legacy/Download/code-2018-creativity.png" – DonAlex1897 Jun 10 '19 at 20:42
  • @mohamadaminkaviyani Can you please accept this answer if it is helpful to you? We can help more people with same problem! – nevermore Jun 10 '19 at 22:50