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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2041717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:56:01  来源:igfitidea点击:

How to delete file after download with ASP.NET MVC?

c#asp.net-mvc

提问by Valentin Vasilyev

I want to delete a file immediately after download, how do I do it? I've tried to subclass FilePathResultand override the WriteFilemethod where I delete file after

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

HttpResponseBase.TransmitFile

is called, but this hangs the application.

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

Can I safely delete a file after user downloads it?

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

采纳答案by Israfel

You could create a custom actionfilter for the action with an OnActionExecuted Method that would then remove the file after the action was completed, something like

您可以使用 OnActionExecuted 方法为操作创建自定义操作过滤器,然后在操作完成后删除文件,例如

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

then your action has

那么你的行动有

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

回答by takepara

My used pattern.

我用过的图案。

1)Create file.

1)创建文件。

2)Delete old created file, FileInfo.CreationTime < DateTime.Now.AddHour(-1)

2)删除旧创建的文件,FileInfo.CreationTime < DateTime.Now.AddHour(-1)

3)User downloaded.

3) 用户下载。

How about this idea?

这个想法怎么样?

回答by Valentin Vasilyev

SOLUTION:

解决方案:

One should either subclass the FileResult or create a custom action filter, but the tricky part is to flush the response before trying to delete the file.

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

回答by biesiad

Create file and save it.
Response.Flush() sends all data to client.
Then you can delete temporary file.

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

This works for me:

这对我有用:

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();

回答by Baz1nga

overriding the OnResultExecuted method is probably the correct solution.. This method runs after the response is written.

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

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

Action code:

动作代码:

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

回答by Alan West

Read in the bytes of the file, delete it, call the base controller's File action.

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

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);
    }
}

BTW, you may refrain from this method if you're dealing with very large files, and you're concerned about the memory consumption.

顺便说一句,如果您正在处理非常大的文件,并且您担心内存消耗,则可以避免使用此方法。

回答by Trax72

Above answers helped me, this is what I ended up with:

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

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);
     }
  }
}

回答by Hrushikesh Patel

Try This. This will work properly.

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

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

回答by Rahul Garg

I performed same action in WebAPI. I needed to delete file just after it downloaded form server. We can create custom response message class. It takes file path as parameter and delete it once its transmitted.

我在 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);
        }
    }

Use this class as below code and it will delete your file once it will be written on response stream.

使用这个类作为下面的代码,一旦它被写入响应流,它就会删除你的文件。

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;

回答by Tejasvi Hegde

Here is updated answer based on elegant solution by @biesiad for ASP.NET MVC ( https://stackoverflow.com/a/4488411/1726296)

这是基于@biesiad 为 ASP.NET MVC 提供的优雅解决方案的更新答案(https://stackoverflow.com/a/4488411/1726296

Basically it returns EmptyResult after response is sent.

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

public ActionResult GetFile()
{
    string theFilename = "<Full path your file name>"; //Your actual file name
        Response.Clear();
        Response.AddHeader("content-disposition", "attachment; filename=<file name to be shown as download>"); //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
}