I want to do something after user finishes downloading
public class TestController : Controller
{
public FilePathResult Index()
{
return File("path/to/file", "mime");
}
}
What I tried is to add the following events to test controller but they all fires before user finish downloading (except destructor it never gets called)
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()
{
//
}
You can try to use custom FileStreamResult as described here - 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;
}
As you see, WriteFile method is overriden and custom logic is implemented to serve response.OutputStream to client by reading chunks from FileStream and writing to OutputStream. At the end of this process you may consider file downloaded. Then you can check DownloadCompleted in OnResultExecuted handler of controller. Alternatively, you can try pass custom Action delegate to CheckedFileStreamResult constructor and invoke that when download completes (instead of using DownloadCompleted flag).
There is ready-made solution for jQuery, check this out http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
The idea is pretty simple: on server-side you create attribute which sets custom cookie after action executed, on client-side you use setTimeout to check this cookie and do something when it'll come.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With