2013-03-08 32 views
11

ASP.NET webapiでは、クライアントに一時ファイルを送信します。ファイルを読み込み、HttpResponseMessageでStreamContentを使用するストリームを開きます。クライアントがファイルを受け取ったら、(クライアントからの他の呼び出しなしで)この一時ファイルを削除します。 クライアントがファイルを受け取ると、HttpResponseMessageのDisposeメソッドは&と呼ばれ、ストリームも破棄されます。今、一時ファイルも削除したいと思います。HttpResponseMessageのStreamContentとして送信されたファイルを削除する方法

HttpResponseMessageクラスからクラスを派生させ、Disposeメソッドをオーバーライドし、このファイルを削除します。&は、基本クラスのdisposeメソッドを呼び出します。 (私はまだ試していないので、これが確実に機能するかどうかはわかりません)

これを達成するためのよりよい方法があるかどうかを知りたいと思います。実際

+1

上記のアプローチが動作しているようですが、内容はファイルが削除される前に配置する必要があります(ファイルへのストリームがまだ開いているよう)(廃棄ブール値) '保護されたオーバーライドボイドのDispose { コンテンツ。 Dispose(); FileInfoファイル=新しいFileInfo(_localFile); file.Delete(); base.Dispose(disposing); } ' –

答えて

13

your commentが問題を解決する助け...私はここでそれについて書いた:

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

をここでは私のために働いたものです。 Dispose内部呼び出しの順序があなたのコメントは異なることに注意してください:

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

追加するだけで、同じ質問がこの回答の1か月後に尋ねられました[ここ](http://stackoverflow.com/questions/20137283/web-api-how-to-detect-when-a-応答完了済み)、これはこれと似ています。しかし、 'HttpResponseMessage'をサブクラス化する代わりに、' StreamContent'でそれを行います。私は、問題の問題に近づくにつれて(問題の少ない動作を優先して)、Content.Dispose();への明示的な呼び出しを避けて、より快適に仕事をしているように感じます。 – Chopin

+0

このようなアプローチには非常に注意してください。 'Dispose(bool)'メソッドは、 'Dispose()'とファイナライザの両方から呼び出されます。ファイナライザーは決して投げてはいけません。ですから、 'disposing'をテストし、' disposing'が真であれば 'File.Delete'を呼び出すほうがよいでしょう。 –

3

私は応答を返す、その後、ファイルを削除する、[]最初のバイトにファイルを読み込むことでそれをやった:

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

あなたのファイルがあまりにも大きくないことを願っています。 –

4

DeleteOnCloseオプションを持つFileStreamからStreamContentを作成します。

return new HttpResponseMessage(HttpStatusCode.OK) 
{ 
    Content = new StreamContent(
     new FileStream("myFile.txt", FileMode.Open, 
       FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose) 
    ) 
}; 
関連する問題