在HttpHandler完成执行后运行代码

时间:2018-06-18 14:20:58

标签: c# asp.net .net httphandler ihttphandler

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

如果您查找HttpResponse.TransmitFile,则会注意到它不会将文件流缓冲到内存中。

  

将指定文件直接写入HTTP响应输出流,而无需将其缓存在内存中。

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


示例实现

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

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)