7

選択したファイルをコントローラーからダウンロードできるMVC4のファイルブラウザーアプリケーションがあります。

現在、FileResultは、他の応答ヘッダーとともにファイルのストリームを返します。これは小さいファイルでは問題なく機能しますが、大きいファイルはOutOfMemoryExceptionを生成します。

私がやりたいのは、WebFormsのHttpReponse.TransmitFileと同様の方法で、メモリにバッファリングせずに、コントローラからファイルを送信することです。

これはどのように達成できますか?

4

3 に答える 3

14

ファイルの結果を返す前に、応答バッファーを無効にすることができます。

Response.BufferOutput = false;
return File(fileStream, contentType);
于 2016-06-11T02:04:44.547 に答える
3

はい、ファイルをストリーミングするためにWeb Apiを使用することで可能です。この記事をご覧ください、 ASP.NETWebAPIでの大きなファイルの処理

于 2012-10-03T14:02:43.843 に答える
0

構成を説明する上記のリンクに加えて、TransmitFileを使用してファイルを「ストリーミング」することができます。ただし、TransmitFileには、一部のhttpクライアントで逆方向があります。

これは、TransmitFileの代わりに、ファイルをクライアントに「ストリーミング」するための私のコードです。WriteFileでロールバックする構成定数があることに注意してください(これはあなたと同じOutOfMemoryの問題があります):

    private void RenderContent(string contentType,string fileName, bool inline);

メソッドコード:

FileInfo fi = new FileInfo(fileName);

Response.ClearHeaders();
Response.ClearContent();

Response.ContentType = contentType;
Response.CacheControl = "No-cache";
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.AddHeader("Content-Length", fi.Length.ToString());
Response.AddHeader("Content-Disposition", (inline ? "inline" : "attachment") + "; filename=\"" + fi.Name + "\"");

if (cAppInfos.Constant["FallBackToWriteFile"] != null && cAppInfos.Constant["FallBackToWriteFile"] == "true")
{
    Response.WriteFile(fileName);
}
else
{
    int chunkSize = 8192;
    byte[] buffer = new byte[chunkSize];
    int offset = 0;
    int read = 0;
    using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        while ((read = fs.Read(buffer, offset, chunkSize)) > 0)
        {
            if (!Response.IsClientConnected)
                break;

            Response.OutputStream.Write(buffer, 0, read);
            Response.Flush();
        }
    }
}

このコードを使用して、古いacrobatリーダープラグインにPDFファイルをストリーミングする際の問題を回避しました。インラインパラメータには、「false」を使用できます。

さらに、Response.IsClientConnecter / Write / Flushのいずれかがクライアントの切断時に例外をスローする可能性があるため、このコードの周りでtry/catchを使用できます。

ただし、私はMVCを使用しておらず、TransmitFileを使用していない場合と同じように、このテクノでこれが受け入れられるかどうかはわかりません。このコードでも同じ問題が発生する可能性があります。ファイルをWebページ要素に埋め込もうとしている場合(base64のように?)、これは解決策ではありません。

目標を達成するために他の方法が必要な場合は、要件について詳しく教えてください。

于 2012-10-03T14:30:28.583 に答える