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:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With