调用Web API获取流文件

问题描述 投票:0回答:1

我正在尝试制作一个应用程序 Blazor Server, 我需要调用一个返回文件的 Web API 方法,我尝试了几次 网上有一些例子,但我总是收到相同的错误消息。

Web API 端

[HttpGet("ExportEmployeesCsv2")]
public async Task<IActionResult> ExportEmployeesCsv()
{
    var path = Path.Combine(Directory.GetCurrentDirectory(), "tmp", "test.csv");
    // Read file into memory
    var memory = new MemoryStream();
    using (var stream = new FileStream(path, FileMode.Open))
    {
        await stream.CopyToAsync(memory);
    }

    memory.Position = 0;
    return File(memory, "text/csv", Path.GetFileName(path));
}

Blazor 面

private async Task DownLoadFile()
    {
        serviceEndpoint = $"{Config.GetValue<string>("WAPIUrl")}ExportEmployeesCsv2/";
        var result = await httpClient.GetAsync(serviceEndpoint);
        if(!result.IsSuccessStatusCode) 
        {
            await JS.InvokeVoidAsync("Alert", "not found");
        }
        else
        {
            var fileStream = result.Content.ReadAsStream();
            using var streamRef = new DotNetStreamReference(stream: fileStream);
            JS.InvokeVoidAsync("downloadFileFromStream", "test.csv", streamRef);
        }          
    }

    

_主机.cshtml

<script>
      window.downloadFileFromStream = async (fileName, contentStreamReference) => {
        const arrayBuffer = await contentStreamReference.arrayBuffer();
        const blob = new Blob([arrayBuffer]);
        const url = URL.createObjectURL(blob);
        const anchorElement = document.createElement('a');
        anchorElement.href = url;
        anchorElement.download = fileName ?? '';
        anchorElement.click();
        anchorElement.remove();
        URL.revokeObjectURL(url);
      }
</script>

尝试过几次后我可能会放弃

错误信息

blazor.server.js:1  [2024-03-19T07:58:26.463Z] Error: System.ObjectDisposedException: Cannot access a closed Stream.
   at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.MemoryStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.<>c__DisplayClass49_0.<<SendDotNetStreamAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c__11`1.<<InvokeAsync>b__11_0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.SendDotNetStreamAsync(DotNetStreamReference dotNetStreamReference, Int64 streamId, Byte[] buffer)

有人可以帮助我吗?我不太了解所有事情,我是一名老 Webform 程序员,我正在努力适应,但这并不容易。

.net .net-core blazor blazor-server-side
1个回答
0
投票

你可以在 blazor 端尝试一下吗?我刚刚将 wait 添加到异步方法并更改了文件读取方式。

private async Task DownLoadFile()
{
    serviceEndpoint = $"{Config.GetValue<string>("WAPIUrl")}ExportEmployeesCsv2/";
    var result = await httpClient.GetAsync(serviceEndpoint);
    if (!result.IsSuccessStatusCode)
    {
        await JS.InvokeVoidAsync("Alert", "not found");
    }
    else
    {
        var contentBytes = await result.Content.ReadAsByteArrayAsync();

        using var fileStream = new MemoryStream(contentBytes);
        using var streamRef = new DotNetStreamReference(stream: fileStream);
        await JS.InvokeVoidAsync("downloadFileFromStream", "test.csv", streamRef);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.