FilePathResult的已完成事件

本文关键字:事件 已完成 FilePathResult | 更新日期: 2023-09-27 18:11:00

我想在用户完成下载后做一些事情

public class TestController : Controller
{
    public FilePathResult Index()
    {
        return File("path/to/file", "mime");
    }
}

我尝试的是将以下事件添加到测试控制器,但它们都在用户完成下载之前触发(除了析构函数,它从未被调用)

protected override void EndExecute(IAsyncResult asyncResult)
{
    base.EndExecute(asyncResult);
}
protected override void EndExecuteCore(IAsyncResult asyncResult)
{
    base.EndExecuteCore(asyncResult);
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    base.OnActionExecuted(filterContext);
}
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
    base.OnResultExecuted(filterContext);
}
protected override void Dispose(bool disposing)
{
    base.Dispose(disposing);
}
~TestController()
{
    //
}

FilePathResult的已完成事件

您可以尝试使用此处描述的自定义FileStreamResult - http://odetocode.com/blogs/scott/archive/2010/06/23/checking-client-download-success-with-asp-net-mvc.aspx.

public class CheckedFileStreamResult : FileStreamResult
{
    public CheckedFileStreamResult(FileStream stream, string contentType)
        :base(stream, contentType)
    {
        DownloadCompleted = false;
    }
    public bool DownloadCompleted { get; set; }
    protected override void WriteFile(HttpResponseBase response)
    {
        var outputStream = response.OutputStream;
        using (FileStream)
        {
            var buffer = new byte[_bufferSize];
            var count = FileStream.Read(buffer, 0, _bufferSize);
            while(count != 0 && response.IsClientConnected)
            {                 
                outputStream.Write(buffer, 0, count);
                count = FileStream.Read(buffer, 0, _bufferSize);
            }
            DownloadCompleted = response.IsClientConnected;
        }
    }
    private const int _bufferSize = 0x1000;
}

如您所见,WriteFile方法被重写,自定义逻辑被实现以提供响应。通过从FileStream读取块并写入OutputStream到客户端。在此过程结束时,您可以考虑文件下载。然后你可以在控制器的onresultperformed handler中检查DownloadCompleted。或者,您可以尝试将自定义动作委托传递给CheckedFileStreamResult构造函数,并在下载完成时调用它(而不是使用DownloadCompleted标志)。

有现成的jQuery解决方案,看看这个http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
这个想法很简单:在服务器端你创建属性设置自定义cookie后执行的动作,在客户端你使用setTimeout来检查这个cookie,并做一些事情当它来了

客户端(浏览器)正在进行下载,当完成时不通知服务器。使用HTTP,您不能告诉客户端在下载后做其他事情。

如果你想在服务器上做一些事情,也许你可以使用PushStreamContent。这里是stackoverflow的答案和一个博客条目。

通常需要两个线程,一个用于下载,一个用于通知。在服务器端,这些线程共享关于从文件长度中发送了多少字节的信息。下载线程是通过IHttpHandler创建的,在IHttpHandler中,您解析http查询并逐个缓冲区地将字节写入http响应缓冲区,并使用通知线程更新共享信息。通知线程是来自您开始下载的页面的一些重复ajax查询。你也可以用jquery渲染下载进度条。