2013-03-08 10 views
11

W webapi ASP.NET, wysyłam plik tymczasowy do klienta. Otwieram strumień, aby odczytać plik i użyć strumienia StreamContent w HttpResponseMessage. Po otrzymaniu pliku przez klienta chcę usunąć ten tymczasowy plik (bez żadnego innego połączenia od klienta). Po otrzymaniu pliku przez klienta metoda Dispose w HttpResponseMessage nosi nazwę & strumień jest również usuwany. Teraz chcę również usunąć tymczasowy plik w tym momencie.Jak usunąć plik, który został wysłany jako StreamContent z HttpResponseMessage

Jednym ze sposobów jest wyprowadzenie klasy z klasy HttpResponseMessage, przesłonięcie metody Dispose, usunięcie tego pliku & wywołanie metody dispose klasy podstawowej. (Jeszcze nie próbowałem, więc nie wiem, czy to działa na pewno)

Chcę wiedzieć, czy istnieje lepszy sposób na osiągnięcie tego.

+1

Powyższe podejście wydaje się działać, ale zawartość musi być usunięte zanim plik zostanie usunięty (jako strumień do pliku jest wciąż otwarta) 'protected override void Dispose (bool wyrzucenie) { zawartość. Dysponować(); FileInfo file = new FileInfo (_localFile); file.Delete(); base.Dispose (usuwanie); } ' –

Odpowiedz

13

Właściwie your comment pomogły rozwiązać pytanie ... Pisałem o tym tutaj:

Delete temporary file sent through a StreamContent in ASP.NET Web API HttpResponseMessage

Oto co pracował dla mnie. Zauważ, że kolejność połączeń wewnątrz Dispose różni się od komentarza:

public class FileHttpResponseMessage : HttpResponseMessage 
{ 
    private string filePath; 

    public FileHttpResponseMessage(string filePath) 
    { 
     this.filePath = filePath; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 

     Content.Dispose(); 

     File.Delete(filePath); 
    } 
} 
+2

Aby dodać, to samo pytanie zostało zadane miesiąc po tej odpowiedzi, [tutaj] (http://stackoverflow.com/questions/20137283/web-api-how-to-detect-whena-a- odpowiedź-zakończyło się-wysłaniem-wysłaniem) i jest podobna do tej. Ale zamiast podklasy 'HttpResponseMessage', robi to z' StreamContent'. Czuję się bardziej komfortowo, wykonując tę ​​pracę w ten sposób, ponieważ jest bliższy problemowi (przesłonięcie mniejszego zachowania), unikając wyraźnego wołania do 'Content.Dispose();' – Chopin

+0

Bądź bardzo ostrożny z takimi podejściami. Metoda "Dispose (bool)" ma być wywoływana zarówno z "Dispose()", jak iz finalizerów. Finalizatorzy NIGDY nie mogą rzucać. Więc prawdopodobnie chciałbyś przetestować "disposing" i wywołać tylko 'File.Delete', jeśli" disposing "jest prawdziwe. –

3

Zrobiłem to przez pierwsze czytanie pliku do byte [], usuwanie pliku, a następnie powrocie odpowiedź:

 // Read the file into a byte[] so we can delete it before responding 
     byte[] bytes; 
     using (var stream = new FileStream(path, FileMode.Open)) 
     { 
      bytes = new byte[stream.Length]; 
      stream.Read(bytes, 0, (int)stream.Length); 
     } 
     File.Delete(path); 

     HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     result.Content = new ByteArrayContent(bytes); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     result.Content.Headers.Add("content-disposition", "attachment; filename=foo.bar"); 
     return result; 
+1

Mam nadzieję, że twoje pliki nie są zbyt duże. –

4

Utwórz StreamContent ze strumienia FileStream posiadającego DeleteOnClose.

return new HttpResponseMessage(HttpStatusCode.OK) 
{ 
    Content = new StreamContent(
     new FileStream("myFile.txt", FileMode.Open, 
       FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose) 
    ) 
}; 
Powiązane problemy