我想在返回临时文件后删除它。我如何使用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 !!
}
文件太大,无法使用内存流返回。
答案 0 :(得分:2)
File()或PhysicalFile()将delegates processing派生到FileResult
的类返回给执行者服务。 PhysicalFileResult
的{{3}}方法调用:
var executor = context.HttpContext.RequestServices
.GetRequiredService<IActionResultExecutor<PhysicalFileResult>>();
return executor.ExecuteAsync(context, this);
所有其他基于FileResult的类都以类似的方式工作。
ExecuteResultAsync类实际上是将文件的内容写入Response流。
一种快速而肮脏的解决方案是创建您自己的基于PhysicalFileResult
的类,该类委派给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)
{
await base.ExecuteResultAsync(context);
File.Delete(FileName);
}
}
您可以创建并返回一个PhysicalFile()
,而不是调用PhysicalFileResult
来创建TempPhysicalFileResult
,例如:
return new TempPhysicalFileResult(file, "application/zip"){FileDownloadName=fileName};
PhysicalFileResultExecutor的操作与此相同:
[NonAction]
public virtual PhysicalFileResult PhysicalFile(
string physicalPath,
string contentType,
string fileDownloadName)
=> new PhysicalFileResult(physicalPath, contentType) { FileDownloadName = fileDownloadName };
更复杂的解决方案是创建一个自定义执行器,该执行器负责压缩和清理文件,而动作代码不包含结果格式代码
答案 1 :(得分:0)
在流完成后直接结束请求的同一请求中,很难做到这一点。更好的选择可能是运行定时后台任务via a hosted service,该任务会定期从temp目录中删除所有文件(例如,上次写入时间大于5分钟的文件)。
答案 2 :(得分:0)
您可以加载文件的内容。删除文件并发送内容作为响应。在MVC中,您可以返回一个文件作为响应。检查下面的代码段
public FileResult Download()
{
var fileName = $"client-file-name.ext";
var filepath = $"filepath";
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
//delete file here
return File(fileBytes, "application/x-msdownload", fileName);
}
答案 3 :(得分:0)
由于文件很大,一种解决方案是在请求旁边发送令牌(如guid)。仅在下载完成后,您才想删除该文件(否则可能会丢失该文件)。因此,使用该令牌,客户端将使用上述令牌发出新请求。因此,您将知道下载成功,并且可以继续删除文件了。
我建议使用字典将令牌映射到文件。
由于您很容易丢失文件,因此删除一个请求似乎是一种不好的做法。
此外,您可以使用Henk Mollema答案来确定是否要定期清除所有文件。