我想在下載後立即刪除文件,我該怎麼做?我試着子類FilePathResult
和覆蓋WriteFile
方法,我如何使用ASP.NET MVC下載後刪除文件?
HttpResponseBase.TransmitFile
被調用後刪除的文件,但是這將使應用程序掛起。
用戶下載後可以安全刪除文件嗎?
我想在下載後立即刪除文件,我該怎麼做?我試着子類FilePathResult
和覆蓋WriteFile
方法,我如何使用ASP.NET MVC下載後刪除文件?
HttpResponseBase.TransmitFile
被調用後刪除的文件,但是這將使應用程序掛起。
用戶下載後可以安全刪除文件嗎?
您可以創建用於與OnActionExecuted法的行動,那麼這將是完成動作後刪除文件的自定義actionfilter,像
public class DeleteFileAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Delete file
}
}
那麼你的動作有
[DeleteFileAttribute]
public FileContentResult GetFile(int id)
{
...
}
我使用的模式。
1)創建文件。
2)刪除舊創建的文件,FileInfo.CreationTime < DateTime.Now.AddHour(-1)
3)用戶下載。
這個想法怎麼樣?
請看我的回答,它現在真的有效 – Valentin 2010-01-11 14:52:21
SOLUTION:
你要麼子類FileResult或者創建自定義操作過濾器,但棘手的部分是刷新試圖刪除文件之前的響應。
創建文件並保存。
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();
重寫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 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);
}
}
順便說一句,如果您處理非常大的文件,並且您關心內存消耗,您可以不要這種方法。
你確定這是這個問題的有效答案嗎? – Oerd 2013-02-07 23:47:33
這是一個非常好的解決方案。我用過這個。謝謝。 – 2013-05-28 01:52:43
+1我喜歡這個比接受的答案更好。沒有必要的屬性或請求刷新,並且代碼很明顯:將文件字節讀入內存,刪除物理文件並將內存中的字節返回給用戶。謝謝! – 2014-01-22 12:25:43
以上的答案幫助我,這就是我結束了:
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);
}
}
}
OnResultExecuted works,onActionExecuted不是 – RAY 2015-12-22 08:54:17
嘗試。這將正常工作。
public class DeleteFileAttribute : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Flush();
string filePath = (filterContext.Result as FilePathResult).FileName;
File.Delete(filePath);
}
}
我在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;
沒有必要調用Content.Dispose() - 它在base.Dispose(diposing)調用中調用。 – 2016-02-17 10:15:48
感謝您的輸入。 – 2016-02-28 17:34:37
這裏是基於@biesiad爲ASP.NET MVC(https://stackoverflow.com/a/4488411/1726296)
基本上發送響應後返回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
}
我已經張貼在https://stackoverflow.com/a/43561635/1726296
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
}
該解決方案可以返回其打開與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的評論。
這對我來說非常合適。在我看來,最簡單的解決方案。 – 2017-11-10 16:01:41
解決方案應該在'答案'中,而不是在問題中。 – 2010-01-11 13:53:37