c# - 在 ASP.NET Core 中流式传输后如何删除文件

标签 c# asp.net-core asp.net-core-mvc

我想在从操作返回后删除一个临时文件。我如何使用 ASP.NET Core 实现这一目标:

public IActionResult Download(long id)
{
    var file = "C:/temp/tempfile.zip";
    var fileName = "file.zip;
    return this.PhysicalFile(file, "application/zip", fileName);
    // I Would like to have File.Delete(file) here !!
}

文件太大,无法使用内存流返回。

最佳答案

File()PhysicalFile()返回一个 FileResult 的派生类,它只是 delegates processing到执行者服务。 PhysicalFileResultExecuteResultAsync方法调用:

var executor = context.HttpContext.RequestServices
                 .GetRequiredService<IActionResultExecutor<PhysicalFileResult>>();
return executor.ExecuteAsync(context, this);

所有其他基于 FileResult 的类都以类似的方式工作。

PhysicalFileResultExecutor类本质上是将文件的内容写入响应流。

一个快速而肮脏的解决方案是创建您自己的基于 PhysicalFileResult 的类,该类委托(delegate)给 PhysicalFileResultExecutor 但在执行程序完成后删除文件:

public class TempPhysicalFileResult : PhysicalFileResult
{
    public TempPhysicalFileResult(string fileName, string contentType)
                 : base(fileName, contentType) { }
    public TempPhysicalFileResult(string fileName, MediaTypeHeaderValue contentType)
                 : base(fileName, contentType) { }

    public override async  Task ExecuteResultAsync(ActionContext context)
    {
        try {
            await base.ExecuteResultAsync(context);
        }
        finally {
            File.Delete(FileName);
        }
    }
}

您可以创建并返回一个 TempPhysicalFileResult,而不是调用 PhysicalFile() 来创建 PhysicalFileResult,例如:

return new TempPhysicalFileResult(file, "application/zip"){FileDownloadName=fileName};

那是一回事PhysicalFile()做:

[NonAction]
public virtual PhysicalFileResult PhysicalFile(
    string physicalPath,
    string contentType,
    string fileDownloadName)
    => new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName };

一个更复杂的解决方案是创建一个自定义执行程序,负责压缩和清理文件,使操作代码与结果格式化代码保持一致

关于c# - 在 ASP.NET Core 中流式传输后如何删除文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54901479/

相关文章:

c# - 将依赖注入(inject)应用于抽象类 c# 的不同实现

c# - 使用 REST API 的设计模式

c# - 如何在 Razor 编辑 View 中显示选中的单选按钮 Asp net core mvc

c# - AspNetCore 1.1 中不存在 OpenIdConnectEvents 中的 AuthenticationValidated 事件,所以我应该在哪里添加声明客户端

c# - 在我的 C# 代码中使用 .NET 4.0 元组是一个糟糕的设计决策吗?

c# - 如何刷新非计算字段的格式并刷新可填写 PDF 表单中的计算字段

c# - 使用 Linq 列表到字典的转换

c# - 在内存中存储数组的最佳实践

asp.net-core - 启动 IIS Express 以运行 ASP.NET Core 应用程序

c# - 禁止 web 应用程序下载 bootstrap 和 jquery