带参数的 Blazor 服务器下载文件

Blazor Server download file with parameters

我有一个 Blazor Server 应用程序,用户可以在其中使用过滤器来查看电影列表。例如,他们可以指定年份、国家等,符合条件的电影将显示在页面上(Movie 个对象的列表)。

我想让用户能够将显示的列表保存为文本文件。我知道如何向另一个 Razor 页面或 MVC 或 API 控制器向 return 预定义文件发出 HTTP Get 请求,但我正在努力将任何参数传递给端点。

最初我想使用 HttpClient.PostAsJsonAsync 向 API 控制器发送 POST 请求,将列表作为请求主体传递,这在某种意义上可以正常工作,如果我在它命中的控制器方法中放置一个断点,但没有任何内容 returned 给用户。

如果我使用 <a> 元素或带有 NavigationManager.NavigateTo 的按钮 onClick 方法,它可以很好地处理预定的文件 HTTP Get 请求,但是我如何为用户提供包含以下内容的文件:他们在浏览器上看到的 movies/objects 列表?

即我如何使用 NavigationManager.NavigateTo 或使用 <a> 元素或任何其他方式传递参数,以便将数据发送到 endpoint/server 然后它可以用来生成文件和 return那个文件给用户保存?

模拟代码让我了解我想要什么。这只是一个 design/idea 参考,不一定是 WebApi、MVC 或其他任何东西。我只需要可以与 Blazor 一起使用的东西:

[HttpPost]
File WebApiMethodThatDoesTheWork(CustomObject data)
{
    StringBuilder stringBuilder = new();
    foreach (var item in data.Items)
    {
        stringBuilder.Append(item);
    }

    File.WriteAllText("test.txt", stringBuilder.ToString());
    return File("test.txt");
}

我对文件的下载方式只有两个要求:它应该是用户友好的,意思是通常的“你想打开还是保存这个文件?”对话框将是完美的并且它不应该使用对 Razor 页面的 GET 请求来检索文件,除非单个 Razor 页面可用于下载许多不同的文件类型。 IE。如果用户想要下载一个电影列表,而另一个是歌曲列表。根据我目前的知识,我认为对于这种情况我必须有 2 个不同的 Razor 页面,这是次优的。

您可以尝试使用该文件重新过滤列表,在启动时您可以检查他们是否有该文件...有很多选项可供您选择

我没有完整的打包答案,因为我的已经很旧了,Blazor 现在的工作方式不同了,但基本原理是一样的。

第 1 步 - JS Interop 调用 URL.createObjectURL(new Blob([{your data}]))

第 2 步 - 使用生成的对象 url 作为 href 和下载属性呈现锚标记。

<a id="download" href=@BlobUrl download=@FileName>Download File</a>

第 3 步 - 可选的 JS Interop 调用以单击呈现的锚标记,因此用户不必这样做。

用户是否看到“另存为..”对话框取决于他们的 browser/operating 系统 - 你无法控制它(下载 api 具有另存为功能,但它不完全支持)