2016-02-11 4 views
6

MVAP 5ベースのWebAPIコントローラを作成しました。これは、お客様のために異なるファイルを提供します。ファイルにアクセスするためのツールも、.NET HttpClientに基づいて自己記述されていますが、それは別の話です。私はthisMVC 5 WebAPI - ダウンロードファイル - HttpException

のようなファイルを提供するためのメカニズムでビルドを使用しました。しかしそのメカニズムは、ファイル> 4ギガバイトのための私のIIS上で墜落したダウンロード制御の最初のバージョンで

だから私は最終的に、このコードに来た:

public class DownloadController : ApiController 
    { 
     public async Task Get(long id) 
     { 
      string fullFilePath = GetFilePathById(id); 
      string returnFileName = fullFilePath.Split('\\').Last(); 
      FileInfo path = new FileInfo(fullFilePath); 
      HttpContext.Current.Response.ContentType = "application/zip"; 
      HttpContext.Current.Response.AddHeader("Content-Length", path.Length.ToString()); 
      HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + returnFileName); 
      HttpContext.Current.Response.Flush(); 
     try 
     { 
      byte[] buffer = new byte[4096]; 
      using (FileStream fs = path.OpenRead()) 
      { 
       using (BufferedStream bs = new BufferedStream(fs, 524288)) 
       { 
        int count = 0; 
        while ((count = bs.Read(buffer, 0, buffer.Length)) > 0) 
        { 
         if (!HttpContext.Current.Response.IsClientConnected) 
         { 
          break; 
         } 
         HttpContext.Current.Response.OutputStream.Write(buffer, 0, count); 
         HttpContext.Current.Response.Flush(); 
        } 
       } 
      } 
     } 
     catch (Exception exception) 
     { 
      //Exception logging here 
     } 
    } 
} 

コードは非常にうまく機能し、私は、I/O許容CPU使用率やディスクに高速ダウンロードを得たこと。 )

Server cannot set status after HTTP headers have been sent 

Exception type: HttpException 

Event Log ID 1309 

私は.Flush(の繰り返し使用することを確信している:未処理の例外は、このようなIISサーバーのアプリケーションイベントログにエントリを書き込みます - すべての単一のダウンロードに - しかし、いくつかの時間後に私は気づい問題を引き起こしますが、これらのいずれかを削除するとダウンロードが停止します。

同様の質問では、私は解決策としてResponse.BufferOutput = true;を見つけることができますが、それは私のすべてのサーバーリソースを食べてダウンロードを遅らせるようです。

どのような提案も素晴らしいでしょう。

+1

最後に 'HttpContext.Current.Response.Close()'を追加しましたか?該当する場合(さらに処理する必要がない場合)、 'HttpContext.Current.ApplicationInstance.CompleteRequest()'? – Jcl

+0

StreamContentを使用していない理由は何ですか? – martennis

+0

@Jcl私はそれを試して、フィードバックをお願いします。 – maltmann

答えて

1

問題がFlush()ではありませんが、応答がHttpContext.Current.Response.Close();

を自分でストリーム閉じていないことをASP.NETフレームワークを使用して、アクションメソッドの内部で何をしているかわからないので、それが通過します私たちの代わりに必要なすべての配管作業を行う通常のリクエストパイプを通じてリクエストしてください。その1つは、ヘッダーとHTTPステータスをクライアントに送信することです。しかし、フレームワークがそれをしようとすると、すでにヘッダーを設定して送信しています。これを避けるには、ストリームを閉じて、応答ストリームを閉じることで処理を終了する必要があります。

+0

を提供するための最良のオプションのようです.Close()はそれを解決しませんでした。 HTTPヘッダーの送信を防ぐ方法を知りましたか? – maltmann

+0

送信されているヘッダーをFiddlerにチェックインできますか? – Tamas

+0

ヘッダーは1回だけ届きます。私はこの例外をグローバルに抑制して、サーバーのイベントログをきれいに保ちます。 – maltmann