简体   繁体   中英

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?

here is how I solved the problem. In fact the solution was really straightforward. Thank you @Data Juggler for pointing me in the right direction.

My Blazor solution holds two project:

  • the server side API (Blazor server)
  • the client side (Blazor WebAssembly).

Here is the code for the server side :

[AllowAnonymous]
[HttpGet("[action]/{p_strPictureFilePath}")]
public IActionResult GetInspectionPicture(string p_strPictureFilePath)
{
  var l_sReader = System.IO.File.OpenRead(p_strPictureFilePath);

  return (File(l_sReader, "application/octet-stream", Path.GetFileName(p_strPictureFilePath)));
}

... and the code on the client side :

Added this script in client-shared.js file:

window.downloadInspectionPicture = function (p_strServerFilePath)
{
  var link = document.createElement('a');
  link.href = 'api/Data/GetInspectionPicture/' + this.encodeURIComponent(p_strServerFilePath);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

of course, a reference to that file is present in index.html :

  <script src="client-shared.js"></script>

And finally, added a link in the razor file, and invoke script when link is clicked:

<a href="javascript:void(0)" @onclick="@(async () => await DownloadPictureAsync())">Download</a>

@code
{
  [Inject]
  IJSRuntime ThisJSRuntime { get; set; }

  private async Task DownloadPictureAsync()
  {
    await ThisJSRuntime.InvokeVoidAsync("downloadInspectionPicture", ServerFilePath);
  }
}

Hope my answer is clear and can be useful to someone

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);
}

I don't know if in fact your way is possible, but what I do is similar for my site https://pixeldatabase.net .

The user clicks the download button, and I show a link like this:

public async void Download()
{
    // Set the ImagePath
    DownloadLink = ImagePath;
}

在此处输入图像描述

Then on the page, I just show a Download link conditionallay:

@if  (HasDownloadLink)
{
    <a class="downloadlink" download="@FileName" href="@DownloadLink" 
target="_blank">Download</a>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM