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

Viewed 39021

I want to delete a file immediately after download, how do I do it? I've tried to subclass FilePathResult and override the WriteFile method where I delete file after

HttpResponseBase.TransmitFile

is called, but this hangs the application.

Can I safely delete a file after user downloads it?

13 Answers

Create file and save it.

Response.Flush() sends all data to client.

Then you can delete temporary file.

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

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

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

then your action has

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

My used pattern.

1)Create file.

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

3)User downloaded.

How about this idea?

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.

I preferred a solution which returned an HttpResponseMessage. I liked the simplicity of Risord's answer, so I created a stream in the same manner. Then, instead of returning a File, I set the HttpResponseMessage.Content property to a StreamContent object.

var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
return new HttpResponseMessage()
{
    Content = new StreamContent(fs)
};
Related