Search code examples
c#asp.net-coreclientblazorwebassembly

Download file from ASP.NET Core api from Blazor client application


I created an ASP.NET Core api controller which return a FileStreamResult object. (I can change the type of result if needed)

Here is the code of the Get function:

[HttpGet("[action]/{p_gInspectionID}/{p_nIndex}")]
public async Task<FileStreamResult> GetInspectionPictureToDownload(Guid p_gInspectionID, int p_nIndex)
{
  var l_strFilePath = await GetPictureFilePathAsync(p_gInspectionID, p_nIndex);

  using (var l_sReader = System.IO.File.OpenRead(l_strFilePath))
  {
    return (File(l_sReader, "image/jpeg"));
  }
}

Now I need to consume this result in the Blazor (Webassembly) client side application.

My goal is to have a button to launch the download of the file in the browser when user clicks on it.

This should launch download functionnality of the browser. Is it possible to achieve this in Blazor client application ?


Solution

  • I was trying to do the same thing, but my API was authorized, so after reading this article I end up downloading the bytes in the web assembly application and use JavaScript to download the file from the bytes.

    function downloadFromByteArray(options: { 
      byteArray: string, 
      fileName: string, 
      contentType: string
    }): void {
    
      // Convert base64 string to numbers array.
      const numArray = atob(options.byteArray).split('').map(c => c.charCodeAt(0));
    
      // Convert numbers array to Uint8Array object.
      const uint8Array = new Uint8Array(numArray);
    
      // Wrap it by Blob object.
      const blob = new Blob([uint8Array], { type: options.contentType });
    
      // Create "object URL" that is linked to the Blob object.
      const url = URL.createObjectURL(blob);
    
      // Invoke download helper function that implemented in 
      // the earlier section of this article.
      downloadFromUrl({ url: url, fileName: options.fileName });
    
      // At last, release unused resources.
      URL.revokeObjectURL(url);
    }