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