2015-09-02 17 views
14

chcę zrobić coś po użytkownik zakończy pobieranieZakończony wydarzeniem dla FilePathResult

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

co starałem się, aby dodać następujące zdarzenia przetestować kontroler ale wszystkie pożary przed zakończeniem użytkownik pobierania (oprócz destructor to nigdy nie jest wywoływana)

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() 
{ 
    // 
} 

Odpowiedz

2

Możesz spróbować użyć niestandardowego obiektu FileStreamResult, jak opisano tutaj - 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; 
} 

Jak widać, metoda WriteFile jest nadpisane i niestandardowe logika jest realizowana służyć response.OutputStream do klienta poprzez czytanie fragmentów z FileStream i pisanie do OutputStream. Pod koniec tego procesu możesz rozważyć pobranie pliku. Następnie możesz sprawdzić funkcję DownloadCompleted w instrukcji OnResultExecuted kontrolera. Alternatywnie można spróbować przekazać niestandardowe delegowanie akcji do konstruktora CheckedFileStreamResult i wywołać to po zakończeniu pobierania (zamiast używać flagi DownloadCompleted).

0

Klient (przeglądarka) robi pobieranie, serwer nie jest informowany o zakończeniu. Dzięki HTTP nie możesz powiedzieć klientowi, aby zrobił coś innego po pobraniu.

+0

Nie chcę mu mówić, żeby zrobił coś innego. Serwer wysyłający strumień, aby wiedział, kiedy to się skończy. – Almis

3

Jest gotowe rozwiązanie dla jQuery, to sprawdzić http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
Pomysł jest całkiem prosty: po stronie serwera utworzyć atrybut, który określa niestandardowy ciastko po działania zrealizowane, na stronie klienta używasz setTimeout do sprawdź to ciasteczko i zrób coś, gdy nadejdzie.

+1

Nie polecam używania plików cookie do czegokolwiek. (chyba, że ​​zanurzone w twoim ulubionym napoju). – ericosg

+0

Jestem bardzo wdzięczny za komentarz. Oczywiście możesz użyć różnych sposobów sprawdzenia niektórych informacji z serwera, ale jest to najszybszy/najprostszy w tym przypadku – HollyDolly

0

Jeśli chcesz coś zrobić na serwerze, możesz użyć PushStreamContent. Here jest odpowiedzią stackoverflow i blog entry.

+0

Czy PushStreamContent oparty jest na SignalR? Czy możesz podać mi jakieś źródło do przeczytania? Chyba opiera się na Headers.TransferEncodingChunked = true .. – user2527768

+0

Masz rację. Myliłem się, to nie zależy od signalR. Usunąłem swój komentarz. – qub1n

+0

Dzięki. Ale skoro usunąłeś swój komentarz, mój wygląda sierotko. – user2527768

0

Generalnie potrzebne są dwa wątki, jeden do pobrania i jeden do powiadomienia. Po stronie serwera wątki te dzielą się informacją o tym, ile wysłano wiele bajtów z długości pliku. Wątek do pobierania jest wykonywany za pośrednictwem IHttpHandler, w którym analizowane jest zapytanie http i zapisywane w bajtach do bufora odpowiedzi HTTP przez bufor i aktualizowane są udostępniane informacje z wątkiem powiadomień. Wątek powiadomienia to powtarzające się kwerendy ajax ze strony, od której zacząłeś pobieranie. Możesz również renderować pasek postępu pobierania za pomocą jquery.

Powiązane problemy