2013-11-22 2 views
9

W sposobie Web API jestem generując plik, a następnie strumieniowego go do odpowiedzi Podobnie jakWeb API - Jak wykryć, gdy reakcja zakończyła wysyłane

public async Task<HttpResponseMessage> GetFile() { 
    FileInfo file = generateFile(); 
    var msg = Request.CreateResponse(HttpStatusCode.OK); 

    msg.Content = new StreamContent(file.OpenRead()); 
    msg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); 
    msg.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {FileName = file.Name}; 

    return msg; 
} 

bo ten wygenerowany plik chcę usuń go po zakończeniu odpowiedzi, ale nie mogę znaleźć haka w przygotowaniu.

Przypuszczam, że mogę umieścić odwołanie do pliku w statycznej i ustawić niestandardowy MessageHandler, który wyciąga wartości z tej samej zmiennej statycznej i usuwa. Wydaje się jednak, że nie może to być słuszne zarówno ze względu na użycie statycznego (gdy wszystko powinno być na żądanie), jak i dlatego, że musiałbym zarejestrować oddzielną trasę.

Widziałem this question, ale wydaje mi się, że nie ma zbytniej przydatnej odpowiedzi.

Odpowiedz

10

Nicea scenariusz! ... problem z użyciem ładowarki wiadomość jest taka, że ​​pisanie odpowiedzi dzieje się warstw zasadniczych i poniżej Ładowarki wiadomość warstwy, więc nie są idealne ...

obserwuję jest przykładem, w jaki sposób może to zrobić:

msg.Content = new CustomStreamContent(generatedFilePath); 

public class CustomStreamContent : StreamContent 
{ 
    string filePath; 

    public CustomStreamContent(string filePath) 
     : this(File.OpenRead(filePath)) 
    { 
     this.filePath = filePath; 
    } 

    private CustomStreamContent(Stream fileStream) 
     : base(content: fileStream) 
    { 
    } 

    protected override void Dispose(bool disposing) 
    { 
     //close the file stream 
     base.Dispose(disposing); 

     try 
     { 
      File.Delete(this.filePath); 
     } 
     catch (Exception ex) 
     { 
      //log this exception somewhere so that you know something bad happened 
     } 
    } 
} 

Nawiasem mówiąc, jesteś wygenerowania tego pliku, ponieważ jest to konwersja niektóre dane w formacie PDF. Jeśli tak, to myślę, że w tym celu można użyć PushStreamContent, bezpośrednio zapisując przekonwertowane dane w strumieniu odpowiedzi. W ten sposób nie musisz najpierw generować pliku, a potem martwić się usunięciem go później.

+0

Dzięki Kiran, próbowałem zrobić coś takiego z deseniem dekoratora i wyciągałem włosy, ponieważ nie mogłem po prostu przesłonić publiczności. W tej notatce (i od kiedy pracujesz w Web Api) masz szansę, aby HttpContent był oparty na interfejsie w przyszłości? –

+0

I tak, generuję plik pdf, ale robię to, wysyłając do phantomjs, więc File jest moim podstawowym formatem wymiany, niestety 'Stream' –

0

Wykonaliśmy tę samą akcję w WebAPI. Musiałem usunąć plik zaraz po pobraniu z serwera. Możemy utworzyć niestandardową klasę wiadomości odpowiedzi. Przyjmuje ścieżkę pliku jako parametr i usuwa go po przesłaniu.

public class FileResponseMessage : HttpResponseMessage 
    { 
     private readonly string _filePath; 

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

     protected override void Dispose(bool disposing) 
     { 
      base.Dispose(disposing); 
      Content.Dispose(); 
      File.Delete(_filePath); 
     } 
    } 

Użyj tej klasy, jak poniżej, a usunie twój plik, gdy zostanie zapisany w strumieniu odpowiedzi.

+0

Powinieneś wykonać kod w metodzie Dispose, kiedy disposing = true. W przeciwnym razie będziesz mieć problemy. –