Pier-Luc Bonneville
Pier-Luc Bonneville
Creator of this blog.
Nov 11, 2020 3 min read

Listing zip file content in Blazor

thumbnail for this post

This is the first post in a series on working with dotnet projects directly in your browser.


Zip files are ubiquitous these days and are one of the (if not the) de facto ways to simultaneously send a collection of files altogether.

In this post, we’ll see how to enumerate and display zip file content in a Blazor WASM application.

The solution

Here is a simple way to achieve this using a flattening the zip structure:


On this page, we have an input file component that accepts zip file.

@page "/"

<h1>Hello, world!</h1>

<div class="drag-drop-zone">
    <InputFile OnChange="OnInputFileChange" accept=".zip" />

@if (_fileName != null)
    if (_entries.Any())
            @foreach (var item in _entries.Where(x => !x.Name.EndsWith("/")))

Once the file has been “uploaded” it’s content will be displayed in a list.


This is the backend of the Index.razor page. On file upload, pass the file stream to the ZipService.

public partial class Index
    private const string DefaultStatus = "Choose a zip file";

    private List<ZipEntry> _entries;
    private string _fileName;

    private string _status = DefaultStatus;

    [Inject] private ZipService ZipService { get; set; }

    private async Task OnInputFileChange(InputFileChangeEventArgs e)
        await using var stream = e.File.OpenReadStream();

        _entries = await ZipService.ExtractFiles(stream);
        _fileName = e.File.Name;

        _status = DefaultStatus;


This is the model we’ll be using to represent the zip file entries.

public record ZipEntry
    public string Name { get; init; }
    public string Content { get; init; }


The ZipService class reads a zip file stream and returns a list of ZipEntry.

public class ZipService
    public async Task<List<ZipEntry>> ExtractFiles(Stream fileData)
        await using var ms = new MemoryStream();
        await fileData.CopyToAsync(ms);

        using var archive = new ZipArchive(ms);

        var entries = new List<ZipEntry>();

        foreach (var entry in archive.Entries)
            await using var fileStream = entry.Open();
            var fileBytes = await fileStream.ReadFully();
            var content = Encoding.UTF8.GetString(fileBytes);

            entries.Add(new ZipEntry { Name = entry.FullName, Content = content });

        return entries;

public static class StreamExtension
    public static async Task<byte[]> ReadFully(this Stream input)
        await using var ms = new MemoryStream();
        await input.CopyToAsync(ms);
        return ms.ToArray();

Remember to register your service

Let’s register our ZipService in the Program class.

public class Program
    public static async Task Main(string[] args)
        var builder = WebAssemblyHostBuilder.CreateDefault(args);

            sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });


        await builder.Build().RunAsync();


Here is a demo of the finished result:


Understandably, this won’t work with encrypted files.

The code covered in this blog post is available here:



  1. How to: Compress and extract files
  2. ASP.NET Core Blazor file uploads