Creé un HttpGet en mi Server-API que crea un archivo CSV y lo devuelve con FileStreamResult :
[HttpGet] public IActionResult Get() { // do logic to create csv in memoryStream return new FileStreamResult(memoryStream, "text/csv;charset=utf-8") { FileDownloadName = "products.csv", }; }En mi aplicación Blazor-Client, he creado un botón con un controlador:
private async Task DownloadCatalog() { var file = HttpClient.GetAsync("api/csvProduct"); // ... how do I download the file in the browser? }Se llama Get in the Controller, pero no sé qué hacer para que el archivo se descargue en el navegador después de la llamada api.
Cuando ejecuta HttpClient.GetAsync , el tiempo de ejecución de Blazor obtiene el archivo. Pero no puede guardar directamente el archivo en el disco porque un entorno de navegador (en el que se ejecuta Blazor) no tiene acceso al disco.
Por lo tanto, deberá usar Javascript Interop para activar la función de descarga de archivos del navegador. Puede generar un enlace data:text/plain;charset=utf-8,<<content of the file>> e invocar hacer clic en él.
Para descargar el archivo, debe usar Microsoft JSInterop. Hay muchas maneras de implementar su solicitud. Una forma que uso es obtener el archivo como una matriz de bytes y luego convertirlo a base64string. Finalmente llame a la función que creó en javascript.
en el lado del servidor
js.InvokeVoidAsync("jsSaveAsFile", filename, Convert.ToBase64String(GetFileByteArrayFunction()) );Y en el archivo javascript en wwwroot creas una función
function jsSaveAsFile(filename, byteBase64) { var link = document.createElement('a'); link.download = filename; link.href = "data:application/octet-stream;base64," + byteBase64; document.body.appendChild(link); link.click(); document.body.removeChild(link);}use el administrador de navegación
@inject NavigationManager NavigationManager private async Task DownloadCatalog() { NavigationManager.NavigateTo("api/csvProduct",true); }