(Estoy usando Blazor Server ejecutando .Net 5, Google Chrome)
Para poder guardar un archivo y ponerlo a disposición del usuario en el navegador, a través de 'archivos descargados', he aprendido que necesita usar javascript.
Para empezar, estoy del lado del servidor de Blazor preparando un archivo, que proviene de un WebAPi como un objeto FileStream.
using (MemoryStream ms = new MemoryStream()) { fsrResponse.Data.FileStream.CopyTo(ms); byteArray = ms.ToArray(); } res= await js.SaveAs(fileName, byteArray);Convierto File Stream en una matriz de bytes que luego se pasa a la tarea SaveAs, que llama a la función javascript después de convertir byteArray en una cadena Base64.
public static async Task<bool> SaveAs(this IJSRuntime js, string filename, byte[] byteArray) { bool ret; try { string bytesBase64 = Convert.ToBase64String(byteArray); ret = await js.InvokeAsync<bool>("saveAsFile", TimeSpan.FromMinutes(1) ,filename, bytesBase64); } catch (Exception ex) { string message = ex.Message; ret = false; } return ret; }Este es el método javascript, que funciona la mayor parte del tiempo.
function saveAsFile(filename, bytesBase64) { var ret; try { var a = document.createElement('a'); a.download = filename; a.target = '_self'; a.href = "data:application/octet-stream;base64," + bytesBase64; document.body.appendChild(a); a.click(); document.body.removeChild(a); ret = true; } catch (e) { ret = false; } return ret; }Este flujo de trabajo funciona perfectamente para archivos de menos de 40-50 MB, pero después de eso, el sitio web se bloquea. Mientras depuro esto, puedo ver que todo funciona hasta que llamo a esta línea de código, después de eso, deja de ejecutarse. No golpea el código javascript en absoluto.
ret = await js.InvokeAsync<bool>("saveAsFile", TimeSpan.FromMinutes(1) ,filename, bytesBase64);No estoy seguro de si esto está relacionado directamente con el tamaño del archivo o si es un problema de tiempo de espera. (Toma alrededor de 33-34 segundos cuando acabo de verificar, antes de que falle.