.NET MAUI Documentation

Downloading Files with .NET MAUI

This tutorial guides you through the process of downloading files from a network in your .NET MAUI applications. We'll cover using the built-in networking capabilities and best practices for handling file downloads.

Prerequisites

Understanding File Downloads

File downloads typically involve sending an HTTP GET request to a specific URL and saving the received data to a local file. .NET MAUI, leveraging the .NET platform, provides robust tools for this.

Using HttpClient

The HttpClient class is the recommended way to make HTTP requests in .NET. It's designed for efficiency and proper resource management.

Basic File Download

Here's a fundamental example of how to download a file using HttpClient:


using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

public async Task DownloadFileAsync(string url, string filePath)
{
    using (var httpClient = new HttpClient())
    {
        try
        {
            var response = await httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode(); // Throws if HTTP status is not 2xx

            using (var contentStream = await response.Content.ReadAsStreamAsync())
            using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                await contentStream.CopyToAsync(fileStream);
            }
            Console.WriteLine($"File downloaded successfully to: {filePath}");
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Request error: {e.Message}");
        }
        catch (IOException e)
        {
            Console.WriteLine($"IO error: {e.Message}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"An unexpected error occurred: {e.Message}");
        }
    }
}
        

Handling Large Files and Progress

For large files, it's crucial to provide user feedback on the download progress. You can achieve this by reading the stream in chunks and updating a progress indicator.

Download with Progress Reporting


using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

public async Task DownloadFileWithProgressAsync(string url, string filePath, IProgress<float> progress)
{
    using (var httpClient = new HttpClient())
    {
        try
        {
            var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
            response.EnsureSuccessStatusCode();

            var totalBytes = response.Content.Headers.ContentLength ?? -1;

            using (var contentStream = await response.Content.ReadAsStreamAsync())
            using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                var buffer = new byte[81920]; // 80KB buffer
                long downloadedBytes = 0;
                int bytesRead;

                while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    await fileStream.WriteAsync(buffer, 0, bytesRead);
                    downloadedBytes += bytesRead;

                    if (totalBytes > 0)
                    {
                        float percentage = (float)downloadedBytes / totalBytes;
                        progress?.Report(percentage);
                    }
                }
            }
            Console.WriteLine($"File downloaded successfully to: {filePath}");
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine($"Request error: {e.Message}");
        }
        catch (IOException e)
        {
            Console.WriteLine($"IO error: {e.Message}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"An unexpected error occurred: {e.Message}");
        }
    }
}
        

In your MAUI view model or code-behind, you would create an instance of Progress<float> and pass it to this method. You can then update UI elements like a ProgressBar in the handler.

Note: Always ensure you have the necessary permissions to write to the specified filePath.

Platform-Specific Considerations

While HttpClient is cross-platform, you might need to consider platform-specific storage locations for downloaded files.

Error Handling and Resilience

Network operations can fail. Implement robust error handling using try-catch blocks to manage HttpRequestException, IOException, and other potential exceptions. Consider retry mechanisms for transient network issues.

Best Practices

By following these guidelines, you can effectively implement file downloading capabilities in your .NET MAUI applications.