Search code examples
htmlasp.net-coreblazorblazor-webassembly.net-8.0

How do I catch a file download start and end in Blazor WASM?


I want to know if anyone has a solution or if its possible to detect/catch the event in Blazor WASM when a file download starts and ends.

So my HTML would be:

<a download href="/api/Download/File">Download</a>

And my backend is something like this:

[HttpGet]
[Route("api/Download/File")]
public async Task<ActionResult> DownloadFile()
{
    try
    {
        // Getting File Data
        return this.File(file.Stream, file.ContentType, file.FileName);
    }
    catch (Exception e)
    {
        return this.StatusCode(StatusCodes.Status500InternalServerError);
    }
}

Is there a way I can catch these events:

  • File started downloading: (I'm guessing '@onclick' could work)
  • File successfully downloaded: ...
  • File download error occurred: ...
  • File download progress: ... (would be nice too)

A solution without JavaScript is best.

Thank you for the answers.

Simon


Solution

  • I want to know if anyone has a solution or if its possible to detect/catch the event in Blazor WASM when a file download starts and ends.

    Well, according to your description and scenario, It's not possible to directly detect or catch file download start and end events within Blazor WASM itself without using JavaScript.

    Because, blazor WASM runs within a WebAssembly sandbox in the browser.This sandboxed environment has limited access to browser APIs, particularly those related to file downloads and events.
    The most importnat point is, blazor's event handling mechanisms are primarily designed for user interactions within the web page itself. This means Blazor's C# code can't directly interact with the download process or its events. So it doesn't extend to external browser events like file downloads.

    However, if you want to try some other alternative, then following way, you can give a shot:

    Depending on your requirement, you can try either of the following ways:

    If you just need basic download completion confirmation and don't require progress tracking or detailed events, using target="_top" on the anchor tag is the most efficient and straightforward approach. It requires minimal code changes and avoids JavaScript complexities. For instance you can do like:

    <a download href="/api/Download/File" target="_top">Download</a>
    

    Above approach, would trigger the download in a new top-level browser window, bypassing Blazor's routing mechanism.

    On the other hand, you can consider sever-side download events specially, For Server-Level Tracking.

    You even can inject JsRuntime as following:

    @inject IJSRuntime JSRuntime
    
    @code {
      protected async Task DownloadFile() {
        await JSRuntime.InvokeVoidAsync("downloadFile");
      }
    }
    

    Finally, considering your requirement and scenario, If you prioritize server-side download tracking for analytics or monitoring purposes, server-side logging within your backend controller is the most efficient way to capture download activity without impacting the client-side Blazor application.

    Note: Please refer to this official document which I think can be resourceful for you.