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

Val*_*yev 31 c# asp.net-mvc

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

HttpResponseBase.TransmitFile
Run Code Online (Sandbox Code Playgroud)

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

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

Ala*_*est 34

读入文件的字节,删除它,调用基本控制器的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 为了获得更好的可伸缩性,您可以切换到FileStreamResult,并且应该使用`FileOptions.DeleteOnClose`打开流本身.这样,在您使用流完成流和ASP之后,将关闭流并自动删除文件.(系统崩溃除外) (16认同)
  • 对于大型文件或大量用户,此解决方案无法扩展.随着用户和/或文件大小的增长,内存消耗将呈指数级增长. (5认同)

bie*_*iad 32

创建文件并保存.
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();
Run Code Online (Sandbox Code Playgroud)


Ris*_*ord 30

您可以只返回常FileStreamResult开的FileOptions.DeleteOnClose.文件流将由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");
Run Code Online (Sandbox Code Playgroud)

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

  • 我强烈推荐这个答案。(记得也支持 Thariq Nugrohotomo 对此答案的评论:/sf/answers/1033416891/) (2认同)

Tra*_*x72 23

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

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);
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • OnResultExecuted有效,onActionExecuted不起作用 (2认同)

Isr*_*fel 14

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

public class DeleteFileAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
        // Delete file 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

然后你的行动了

[DeleteFileAttribute]
public FileContentResult GetFile(int id)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)


Rah*_*arg 6

我在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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)


Baz*_*nga 5

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

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

动作代码:

[DeleteFileAttribute]
public FileContentResult GetFile(int id)
{
   //your action code
}
Run Code Online (Sandbox Code Playgroud)