在HttpHandler完成执行后运行代码

问题描述 投票:1回答:2

HttpHandler负责使用HttpResponse.TransmitFile将文件下载分发给最终用户。下载完成后需要删除此文件,但是如果在HttpResponse.End之前删除文件,则文件丢失且下载失败,并且HttpResponse.End之后的任何代码都不会被执行。

在下载完成并且HttpResponse结束后删除此文件的最佳方法是什么?

public void ProcessRequest(HttpContext context)
{
    HttpResponse r = context.Response;
    string filePath = context.Request.QueryString["filePath"];
    string fName = context.Request.QueryString["fname"];
    r.AddHeader("content-disposition", "inline; filename=\"" + fName + "\"");
    r.TransmitFile(fullPath);
    r.End();
}
c# asp.net .net httphandler ihttphandler
2个回答
0
投票

不完全确定这一点,但.End()引发了EndRequest事件,因此可能会将其添加到您的http处理程序。希望这将足够晚(这是管道中的最后一个事件)。

private void Application_EndRequest(Object source, EventArgs e)
{
    // delete file here.
}

0
投票

鉴于您的要求和问题,您应该使用立即影响HttpResponse.OutputStream的实现。

如果你查找HttpResponse.TransmitFile,你会发现它没有将文件流缓冲到内存中。

将指定文件直接写入HTTP响应输出流,而不在内存中缓冲它。

出于您的目的,您确实希望将其缓冲到内存中;之后,您可以删除该文件。


Example Implementation

实际上,这个answer到另一个SO问题提供了一个适合处理这个问题的实现:

public void ProcessRequest(HttpContext context)
{
    string absolutePath = "~/your path";
    //copy to MemoryStream
    using (MemoryStream ms = new MemoryStream())
    {
        using (FileStream fs = File.OpenRead(Server.MapPath(absolutePath))) 
        { 
            fs.CopyTo(ms); 
        }

        //Delete file
        if(File.Exists(Server.MapPath(absolutePath)))
           File.Delete(Server.MapPath(absolutePath))

        //Download file
        context.Response.Clear()
        context.Response.ContentType = "image/jpg";
        context.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + absolutePath + "\"");
        context.Response.BinaryWrite(ms.ToArray())
    }

    Response.End();
}

请注意,您可以直接写入HttpResponse.OutputStream,而不是在Write对象上使用HttpResponse方法:

File.OpenRead(Server.MapPath(absolutePath)).CopyTo(context.Response.OutputStream)
© www.soinside.com 2019 - 2024. All rights reserved.