C# FilePathResult的事件已完成

C# FilePathResult的事件已完成,c#,asp.net-mvc,controller,fileresult,C#,Asp.net Mvc,Controller,Fileresult,我想在用户完成下载后做一些事情 public class TestController : Controller { public FilePathResult Index() { return File("path/to/file", "mime"); } } 我尝试将以下事件添加到测试控制器,但它们都在用户完成下载之前触发(析构函数除外,它从未被调用) 客户端(浏览器)正在进行下载,下载完成时不会通知服务器。使用HTTP,您无法在下载后告诉客户端执行

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

public class TestController : Controller
{
    public FilePathResult Index()
    {
        return File("path/to/file", "mime");
    }
}
我尝试将以下事件添加到测试控制器,但它们都在用户完成下载之前触发(析构函数除外,它从未被调用)


客户端(浏览器)正在进行下载,下载完成时不会通知服务器。使用HTTP,您无法在下载后告诉客户端执行其他操作。

有现成的jQuery解决方案,请查看此

想法很简单:在服务器端,您创建属性,在执行操作后设置自定义cookie,在客户端,您使用setTimeout检查此cookie,并在它到来时执行一些操作。

如果您想在服务器上执行某些操作,可以使用PushStreamContent。通常您需要两个线程,一个用于下载,一个用于通知。在服务器端,这些线程共享关于文件长度中发送了多少字节的信息。下载线程是通过IHttpHandler进行的,您可以在其中解析http查询,逐个缓冲地将字节写入http响应缓冲区,并使用通知线程更新共享信息。通知线程是您开始下载的页面上的一些重复ajax查询。您还可以使用jquery呈现下载进度条。

您可以尝试使用自定义文件流结果,如下所述-


如您所见,WriteFile方法被重写,自定义逻辑被实现,通过从FileStream读取块并写入OutputStream,为客户机提供response.OutputStream服务。在这个过程结束时,您可以考虑下载文件。然后,您可以在控制器的OnResultExecuted处理程序中检查DownloadCompleted。或者,您可以尝试将自定义操作委托传递给CheckedFileStreamResult构造函数,并在下载完成时调用该构造函数(而不是使用DownloadCompleted标志)。

我不想告诉他做其他事情。服务器正在发送流,以便它应该知道流何时完成。PushStreamContent是否基于Signal?你能提供一些资料给我阅读吗?我想这取决于标题。TransferncodingChunked=true..你是对的。我错了,这不取决于信号员。我删除了我的评论。谢谢。但由于你删除了你的评论,我的评论看起来像孤儿。我不建议再为任何事情使用cookies了。(除非沾上你最喜欢的饮料)。我非常感谢你的评论。当然,您可以使用不同的方法来检查服务器上的一些信息,但在这种情况下,这是最快/最简单的方法
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()
{
    //
}
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;
}