2013-11-22 12 views
9

in einer Web-API-Methode gesendet beendet ich eine Datei bin zu erzeugen und sie dann wie so auf die Antwort StreamingWeb Api - Wie zu erkennen, wenn eine Antwort hat wurde

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

weil dies eine generierte Datei Ich mag lösche es, nachdem die Antwort das Streaming beendet hat, aber ich kann anscheinend keinen Haken in der Pipeline finden.

Ich nehme an, dass ich einen Verweis auf die Datei in einer statischen setzen und einen benutzerdefinierten MessageHandler einrichten kann, die Werte aus dieser statischen Variable zieht und löscht. Dies scheint jedoch unmöglich zu sein, sowohl wegen der Verwendung von statischen Daten (wenn dies alles pro Anfrage sein sollte) als auch wegen der Notwendigkeit, eine separate Route zu registrieren.

Ich habe this question gesehen, aber es scheint nicht wirklich eine sehr nützliche Antwort zu haben.

Antwort

10

Nizza Szenario! ... das Problem mit Nachrichten-Handler ist, dass Antwort Schreiben an den Schicht Host-Schichten und unter Meldungshandler geschieht, so sind sie nicht ideal ...

Es folgt ein Beispiel, wie Sie tun könnte es:

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

By the way, sind Sie diese Datei zu erzeugen, weil Sie einige Daten in PDF konvertieren. Wenn ja, dann könnten Sie PushStreamContent für diesen Zweck verwenden, indem Sie die konvertierten Daten direkt in den Antwortstream schreiben. Auf diese Weise müssen Sie nicht zuerst eine Datei generieren und sich dann darum kümmern, sie später zu löschen.

+0

Dank Kiran, ich habe versucht, so etwas mit einem Dekorateur Muster zu tun und zog mir die Haare aus, weil ich Publikum nicht einfach außer Kraft setzen konnte. In diesem Sinne (und da Sie an Web API arbeiten) besteht die Möglichkeit, dass HttpContent auf einer Schnittstelle in der Zukunft basiert. –

+0

Und yeah, ich erzeuge ein pdf, mache es aber, indem ich phantomjs ausschalte, also ist eine Datei mein grundlegendes Austauschformat, leider kein 'Stream' –

0

Wir führten dieselbe Aktion in WebAPI aus. Ich musste die Datei direkt nach dem Download des Form Servers löschen. Wir können benutzerdefinierte Antwort Nachricht Klasse erstellen. Er nimmt den Dateipfad als Parameter und löscht ihn, sobald er übertragen wurde.

Verwenden Sie diese Klasse als unten stehenden Code und es wird Ihre Datei löschen, sobald sie in Antwort-Stream geschrieben wird.

+0

Sie sollten den Code nur in der Dispose-Methode ausführen, wenn disposing = true ist. Sonst haben Sie Probleme. –

Verwandte Themen