我是这样做的:
在一个名为Controllers的文件夹中添加了一个名为DownloadController.cs的新控制器
[Controller, Microsoft.AspNetCore.Mvc.Route("/[controller]/[action]")]
public class DownloadController : Controller
{
private readonly IDataCombinerService DataCombinerService;
private readonly IDataLocatorService DataLocatorService;
public DownloadController(IDataCombinerService dataCombinerService, IDataLocatorService dataLocatorService)
{
DataCombinerService = dataCombinerService;
DataLocatorService = dataLocatorService;
}
[HttpGet]
[ActionName("Accounts")]
public async Task<IActionResult> Accounts()
{
var cts = new CancellationTokenSource();
var Accounts = await DataCombinerService.CombineAccounts(await DataLocatorService.GetDataLocationsAsync(cts.Token), cts.Token);
var json = JsonSerializer.SerializeToUtf8Bytes(Accounts, Accounts.GetType(), new JsonSerializerOptions(JsonSerializerDefaults.Web) { WriteIndented = true });
var stream = new MemoryStream(json);
var fResult = new FileStreamResult(stream, MediaTypeNames.Application.Json)
{
FileDownloadName = $"Account Export {DateTime.Now.ToString("yyyyMMdd")}.json"
};
return fResult;
}
[HttpGet]
public IActionResult Index()
{
return View();
}
}
严格来说,在这里并不需要异步操作,因为它不需要处理其他任何内容,但是当需要在屏幕上显示相同的结果时,该方法被使用。
然后在 Startup.cs 文件中。
app.UseEndpoints(endpoints =>
添加:
endpoints.MapControllerRoute(
name: "default",
defaults: new { action = "Index" },
pattern: "{controller}/{action}");
endpoints.MapControllers();
再次强调,默认值并非必需,它是标准的MVC控制器。
这样就可以像经典的MVC响应一样运行,因此您可以从任何喜欢的来源发送任何文件。最好有一个中间件服务来在视图和下载控制器之间保存临时数据,以便客户端下载相同的数据。