【问题标题】:Blazor server-side app dies after file downloadBlazor 服务器端应用程序在文件下载后死机
【发布时间】:2021-01-05 17:52:50
【问题描述】:

我有一个 blazor 服务器端应用程序,其中一个页面使用以下代码推送文件下载:

nav.NavigateTo("/download/" + fileName, true);

通过将页面重定向到文件并弹出下载对话框,效果很好。但是,在此操作之后,应用程序会死掉。

错误:电路因错误而关闭。

我必须刷新页面以重新建立连接才能继续。

我应该做一些不同的事情来允许用户下载文件吗?

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案1】:

    对于使用 .NET 5 RC2 的任何人

    如果您使用的是 .NET 5 RC2 或更高版本,则此解决方案将不适用于您,并且上述问题中显示的代码应符合 this issue 的要求。如果您仍然遇到问题,则可能是您遇到了其他问题。

    适用于使用 .NET 5 RC2 之前版本的任何人

    要记住的是,使用 Blazor 时,所有通信都是通过 websocket 进行的。这可能会在处理文件下载时出现问题,因为任何远离套接字的导航(例如导航到静态文件)都会中断连接。

    处理这个问题的一个简单方法是使用像BlazorDownloadFile 这样的包。

    为了使用它,只需使用以下命令安装 nuget:

    Install-Package BlazorDownloadFile -Version 2.1.2
    

    接下来在 Startup.cs 文件的 ConfigureServices 方法中添加以下行:

    services.AddBlazorDownloadFile();
    

    现在您可以注入 IBlazorDownloadFileService 并使用它来下载文件。我在下面包含了一个这样的用法示例,它只是从与正在执行的程序集相同的目录下载文本文件。

    @page "/"
    @using BlazorDownloadFile
    @using System.IO
    @using System.Reflection
    @using System.Threading
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    @Message
    <br/>
    
    <SurveyPrompt Title="How is Blazor working for you?"/>
    
    <button @onclick="OnClicked">Download File</button>
    
    @code{
        [Inject] IBlazorDownloadFileService BlazorDownloadFileService { get; set; }
        public string Message = String.Empty;
        
        public async Task OnClicked()
        {
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestDownloadFile.txt");
            var bytes = File.ReadAllBytes(path);
            var task = await BlazorDownloadFileService.DownloadFile("testdownload.txt", bytes.ToList(),CancellationToken.None,"application/octet-stream");
            if (task.Succeeded)
            {
                Message = "Successful download!";
            }
            else
            {
                Message = task.ErrorMessage;
            }
        }
    
    }
    

    如您所见,这样您就可以轻松地让用户下载文件而不会冒中断 websocket 连接的风险,并且您可以获得有关是否存在问题的反馈,以便实施适当的错误处理。

    Github Project 中提到了一些注意事项,您可能需要注意:

    关于我在这个库中所做的一些性能测试是 也就是说,base64 字符串和 byte[] 的执行速度总是比 Stream 快。

    由于从 c# Stream 到 a JavaScript 对象在这项任务中的开销要大一些。

    当它的 base64 是最简单的数据类型传输和工作 用它。

    byte[] 在传输到 JavaScript,由于某种原因,它在编码时无法正常工作 导致它的base64表示在进行时变成了别的东西 在第二个分区之后被编码为 base64 字符串。 (如果 任何人都知道如何修复或解决此问题,请提出拉取请求)

    基于 las 语句,字节列表从 c# 传递到 JavaScript 作为整数数组,字节表示为 on JavaScript,这就是我发送 IList 而不是 byte[] 在 JavaScript 内部。

    二进制表示似乎表现得很好,因为我们刚刚 需要调用 Uint8Array 并完全推送二进制表示 进入数组,然后将其传递给 JavaScript 原生 Blob 对象。

    【讨论】:

    • 它正在工作,但只是在第一次工作,因为当我想下载另一个文件时没有任何反应。
    • @sada 这里有太多的变数。如果您有基于项目的问题,请随时在此处提出问题,并附上Minimal, Reproducible Example
    【解决方案2】:

    您展示的代码应该可以工作——并且对我有用。这个问题似乎是一个困扰很多人的已知(新)问题。您可以在此处找到有关该问题的更多信息:https://github.com/dotnet/aspnetcore/issues/25646

    他们说他们正在努力解决这个问题,但目前还没有预计到达时间。很抱歉,我没有一个像样的解决方法可以分享——我自己还在探索。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 2020-09-18
    • 2021-10-21
    • 1970-01-01
    • 2020-04-23
    • 2021-10-29
    相关资源
    最近更新 更多