2012-10-03 44 views
5

返回大量數據,我在MVC4文件瀏覽器應用程序,允許您從控制器下載選定的文件。ASP.NET MVC:從FileResult

目前,FileResult返回文件的流,與其他響應標頭。雖然這對較小的文件正常工作,但較大的文件會生成OutOfMemoryException。

我希望做的是在傳輸的WebForms從控制器文件,無需緩衝存儲器的方式類同HttpReponse.TransmitFile。

這是如何實現的?

回答

2

是的,你可以以流的文件使用網絡API,看看這篇文章Dealing with large files in ASP.NET Web API

+0

謝謝 - 當使用環節,添加'GlobalConfiguration.Configuration.Services.Replace(typeof運算(WebHostBufferPolicySelector),新NoBufferPolicySelector())之後;'線,以我的Global.asax.cs文件,我得到的出現以下錯誤:'服務類型WebHostBufferPolicySelector不受支持.'有什麼幫助嗎? –

+0

問題是關於MVC,而不是Web API –

0

Additionaly來描述配置上面的鏈接,你可以使用的TransmitFile以「流」文件。但是,TransmitFile在一些http客戶機上有一些倒退。

這是我的代碼爲「流」文件到客戶端,爲的TransmitFile替代。請注意,我有一個配置不變也是跟WriteFile回滾(具有相同的內存溢出問題,因爲你的):

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

我用這個代碼,以避免一些問題將pdf文件傳輸到舊的acrobat reader插件。對於inline參數,您可以使用「false」。

Additionaly,你可以使用的try/catch解決此代碼,因爲任何Response.IsClientConnecter /寫/沖洗的可以拋出,如果客戶端斷開連接的異常。

不過,我沒有使用MVC,我不知道這是可以接受的這種TECHNO,因爲如果你還沒有使用的TransmitFile,你可能會堅持使用此代碼相同的問題。 如果您試圖將文件嵌入到網頁元素(如base64也許?),這不是解決方案。

讓我更瞭解您的需求,如果您需要其他方法來實現您的目標。

+0

另外,將結果呈現爲「流文件」的選擇在控制器中可能不相關,並且可能會在演示中移動,您可以在其中訪問Response對象。 控制器可能只是要求表示層流...文件流/文件名? – Echtelion

+0

爲了迴應你的「控制器可能只是要求表示層流... ...」的評論,因爲它必須以同樣的方式服務流,這是否會在不同的位置引入相同的問題? –

+0

我不是一名MVC專家,但我建議您將問題移到可以解決問題的地方(例如:可訪問Response對象的地方) – Echtelion

8

您可以在返回文件結果之前禁用響應緩衝區。

Response.BufferOutput = false; 
return File(fileStream, contentType); 
+1

這是唯一適用於我的(乾淨的)解決方案, 謝謝! –

+1

請注意,對於非常大的文件(2GB +),您還需要設置'HttpCompletionOption.ResponseHeadersRead'以防止'不能向配置的最大緩衝區大小寫入更多字節:2147483647.'例外。 –

相關問題