用ASP.NET MVC下载后如何删除文件?

我想在下载后立即删除文件,我该怎么办? 我试图FilePathResult并覆盖我删除文件后的WriteFile方法

 HttpResponseBase.TransmitFile 

被调用,但这会挂起应用程序。

用户下载后可以安全删除文件吗?

您可以使用OnActionExecuted方法为操作创建自定义actionfilter,然后在操作完成后删除该文件,类似于

 public class DeleteFileAttribute : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { // Delete file } } 

然后你的行动了

 [DeleteFileAttribute] public FileContentResult GetFile(int id) { ... } 

读入文件的字节,删除它,调用基本控制器的File操作。

 public class MyBaseController : Controller { protected FileContentResult TemporaryFile(string fileName, string contentType, string fileDownloadName) { var bytes = System.IO.File.ReadAllBytes(fileName); System.IO.File.Delete(fileName); return File(bytes, contentType, fileDownloadName); } } 

顺便说一下,如果你处理的是非常大的文件,你可能会避免使用这种方法,而你却担心内存消耗。

创建文件并保存。
Response.Flush()将所有数据发送到客户端。
然后你可以删除临时文件。

这对我有用:

 FileInfo newFile = new FileInfo(Server.MapPath(tmpFile)); //create file, and save it //... string attachment = string.Format("attachment; filename={0}", fileName); Response.Clear(); Response.AddHeader("content-disposition", attachment); Response.ContentType = fileType; Response.WriteFile(newFile.FullName); Response.Flush(); newFile.Delete(); Response.End(); 

以上答案对我有帮助,这就是我最终的结果:

 public class DeleteFileAttribute : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Flush(); var filePathResult = filterContext.Result as FilePathResult; if (filePathResult != null) { System.IO.File.Delete(filePathResult.FileName); } } } 

您可以返回使用FileOptions.DeleteOnClose打开的常规FileStreamResult 。 文件流将由asp.net处理结果。 这个答案不需要使用低级响应方法,这些方法可能会在某些情况下适得其反。 此外,不会进行额外的工作,例如将文件整体加载到内存中。

 var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose); return File( fileStream: fs, contentType: System.Net.Mime.MediaTypeNames.Application.Octet, fileDownloadName: "File.abc"); 

这个答案是基于Alan West的回答和Thariq Nugrohotomo的评论。

我在WebAPI中执行了相同的操作。 我需要在下载表单服务器之后删除文件。 我们可以创建自定义响应消息类。 它将文件路径作为参数,并在传输后将其删除。

  public class FileHttpResponseMessage : HttpResponseMessage { private readonly string filePath; public FileHttpResponseMessage(string filePath) { this.filePath = filePath; } protected override void Dispose(bool disposing) { base.Dispose(disposing); File.Delete(filePath); } } 

使用此类作为下面的代码,一旦将其写入响应流,它将删除您的文件。

 var response = new FileHttpResponseMessage(filePath); response.StatusCode = HttpStatusCode.OK; response.Content = new StreamContent(new FileStream(filePath, FileMode.Open, FileAccess.Read)); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "MyReport.pdf" }; return response; 

重写OnResultExecuted方法可能是正确的解决方案..此方法在写入响应后运行。

 public class DeleteFileAttribute : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Flush(); // Delete file } } 

行动代码:

 [DeleteFileAttribute] public FileContentResult GetFile(int id) { //your action code } 

试试这个。 这将正常工作。

 public class DeleteFileAttribute : ActionFilterAttribute { public override void OnResultExecuted( ResultExecutedContext filterContext ) { filterContext.HttpContext.Response.Flush(); string filePath = ( filterContext.Result as FilePathResult ).FileName; File.Delete( filePath ); } } 

我使用的模式。

1)创建文件。

2)删除旧的创建文件,FileInfo.CreationTime

3)用户下载。

这个想法怎么样?

解:

应该将FileResult子类化或创建自定义操作filter,但棘手的部分是在尝试删除文件之前刷新响应。

以下是@biesiad针对ASP.NET MVC的优雅解决方案的更新答案( https://stackoverflow.com/a/4488411/1726296

基本上它在发送响应后返回EmptyResult。

 public ActionResult GetFile() { string theFilename = ""; //Your actual file name Response.Clear(); Response.AddHeader("content-disposition", "attachment; filename="); //optional if you want forced download Response.ContentType = "application/octet-stream"; //Appropriate content type based of file type Response.WriteFile(theFilename); //Write file to response Response.Flush(); //Flush contents Response.End(); //Complete the response System.IO.File.Delete(theFilename); //Delete your local file return new EmptyResult(); //return empty action result } 

我已在https://stackoverflow.com/a/43561635/1726296中发布此解决方案

 public ActionResult GetFile() { string theFilename = ""; //Your actual file name Response.Clear(); Response.AddHeader("content-disposition", "attachment; filename="); //optional if you want forced download Response.ContentType = "application/octet-stream"; //Appropriate content type based of file type Response.WriteFile(theFilename); //Write file to response Response.Flush(); //Flush contents Response.End(); //Complete the response System.IO.File.Delete(theFilename); //Delete your local file return new EmptyResult(); //return empty action result }