admin管理员组

文章数量:1291050

I have this method in my blazor web app which I use to get a files' url from my api. The files are already uploaded in AzureBlobStorage and when I try to download them directly from the URL that my API provides me, I can open them and they're all fine.

However, when I try it with my methods, the download is successful but the I cannot open them since they seem to be corrupted.

My blazor method:

public async Task DownloadStream(FileProperties file)
{
    DisableButton = true;

    try
    {
        var blobUrl = await _httpClient.GetBlobUrl(file.Id.ToString());

        await _jsRuntime.InvokeVoidAsync("fileDownload", blobUrl, file.Name);
        

    }
    catch (Exception ex)
    {
        Console.WriteLine("ERROR: JS method missing... " + ex.Message);
    }

    DisableButton = false;
}

My Javascript method that I invoke in my method:

function fileDownload(base64String, fileName) {
    console.log("url=", base64String);
    const a = document.createElement("a");
    a.href = base64String;
    a.download = fileName;
    a.target = "_blank"; // Open in new tab if needed
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

What am I missing here?

I have this method in my blazor web app which I use to get a files' url from my api. The files are already uploaded in AzureBlobStorage and when I try to download them directly from the URL that my API provides me, I can open them and they're all fine.

However, when I try it with my methods, the download is successful but the I cannot open them since they seem to be corrupted.

My blazor method:

public async Task DownloadStream(FileProperties file)
{
    DisableButton = true;

    try
    {
        var blobUrl = await _httpClient.GetBlobUrl(file.Id.ToString());

        await _jsRuntime.InvokeVoidAsync("fileDownload", blobUrl, file.Name);
        

    }
    catch (Exception ex)
    {
        Console.WriteLine("ERROR: JS method missing... " + ex.Message);
    }

    DisableButton = false;
}

My Javascript method that I invoke in my method:

function fileDownload(base64String, fileName) {
    console.log("url=", base64String);
    const a = document.createElement("a");
    a.href = base64String;
    a.download = fileName;
    a.target = "_blank"; // Open in new tab if needed
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

What am I missing here?

Share Improve this question edited Feb 14 at 9:20 Jason Pan 21.9k2 gold badges19 silver badges43 bronze badges asked Feb 13 at 16:15 Leo RamadaniLeo Ramadani 2191 silver badge11 bronze badges 6
  • Does _httpClient.GetBlobUrl(file.Id.ToString()) return a URL or does it return a Base64 string? Your code is confusing because the fileDownload js function expects a base64String as the first parameter but your C# DownloadStream method appears to be downloading a url. – pnavk Commented Feb 13 at 23:07
  • How big is the file? There are limitations here. You don't have to use js to build an anchor with a base64 content. You could also create a file download controller and use blazor to create a download link from that, this gives you better browser caching as well... – Brian Parker Commented Feb 14 at 6:32
  • @pnavk it returns a URL, the parameter name in js function was a typo. – Leo Ramadani Commented Feb 14 at 8:10
  • @BrianParker the files are from 50kb to 1.3 gb. But it doesn't work with the small ones either. Also when I try with blazor I get to use MemoryStream which will try to download and read all the bytes and this will throw an exception of "memory out of bound". So my only way out is through a js method. – Leo Ramadani Commented Feb 14 at 8:12
  • 1 Please try to use XMLHttpRequest to download the file, and set responseType = "blob", you can find my sample code in function bb(). – Jason Pan Commented Feb 14 at 9:20
 |  Show 1 more comment

1 Answer 1

Reset to default 0

This is the code behind I used for a base64 image prototype. I actually abandoned it and went with a file download controller method. I found performance, size, and browser caching issues this way.

The orchestration service is returning the blob stream.

public partial class DocumentBase64Img : ComponentBase
{
    private readonly IDocumentOrchestrationService documentOrchestrationService;
    private string? base64;

    public DocumentBase64Img(IDocumentOrchestrationService documentOrchestrationService)
    {
        this.documentOrchestrationService = documentOrchestrationService;
    }

    [Parameter]
    public string FileName { get; set; } = default!;

    [Parameter]
    public int Width { get; set; } = default!;


    protected override async Task OnInitializedAsync()
    {
        var streamResult = await documentOrchestrationService.GetDocumentStreamAsync("container-name", FileName);

        if (streamResult.IsSuccess)
        {
            var stream = streamResult.Value;

            // copy all bytes to a buffer
            using (var memoryStream = new MemoryStream())
            {
                stream.Seek(0, SeekOrigin.Begin);
                await stream.CopyToAsync(memoryStream).ConfigureAwait(false); // copy stream to memoryStream
                byte[] buffer = memoryStream.ToArray();

                var base64 = Convert.ToBase64String(buffer);
                this.base64 = $"data:image/jpeg;base64,{base64}";
                await InvokeAsync(StateHasChanged);
            }
        }
    }
}

Note: .Net 9 Blazor allows injecting via the constructor...

<img src="@base64" width="@Width" />

本文标签: javascriptFile downloaded from BlobStorage are corruptedStack Overflow