簡體   English   中英

如何在ASP.NET MVC中支持大尺寸內容

[英]how to support big size content in asp.net mvc

通常,我必須從我的應用程序中的數據庫創建csv導出文件。 當我必須創建15 MB的導出文件時,我會遇到mvc問題,因為要使用return Content();。 ,我需要在內存中創建包含所有數據的大字符串,並且經常出現內存異常,因此我必須使用.aspx頁,在處理數據的同時可以在其中使用Response.Write進行操作。

嘗試使用mvc的第二個問題是,如果我必須進行長時間處理,那么在我尚未完成詳細說明並開始發送它之前,客戶端什么都看不到,並且通常認為這是連接或服務器問題。

是否可以在mvc中執行動作的過程中將數據發送到內容,而不結束處理的完成?

這是一段可以解決此問題的代碼。 請注意,盡管您可以使用Web API並僅創建CSV格式程序(並禁用輸出緩沖)或直接使用pushtreamcontent。

對於MVC,這是一個示例代碼,請注意,此示例使用閉包,但您可以同樣使用IEnumerable。 關鍵是使求值延遲,因此您不必在內存中創建整個字符串。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;

namespace SampleApplication
{
    public class HomeController : Controller
    {
        public ActionResult LargeCsv()
        {
            // TODO: Replace the func with real data access, or alternatively use an IQueryable/IEnumerable/IEnumerator implementation 
            // to access the data dynamically.
            int i = 0;
            Func<string> func = () =>
            {
                while (i < 100)
                {
                    i++;
                    return "Name" + i + ", " + i;
                }

                return null;
            };

            return new CsvActionResult(func);
        }
    }

    public class CsvActionResult : ActionResult
    {
        private readonly Func<string> _getNextCsvLine;

        public CsvActionResult(Func<string> getNextCsvLine)
        {
            _getNextCsvLine = getNextCsvLine;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.Headers.Add("Content-Type", "text/csv");

            context.HttpContext.Response.BufferOutput = false;

            // StreamWriter has inherent buffering so this operation is reasonably performant, it 
            // is going to write buffers to the wire rather than each writeline.
            using (StreamWriter sw = new StreamWriter(context.HttpContext.Response.OutputStream))
            {
                string csvLine;

                do
                {
                    csvLine = _getNextCsvLine();
                    sw.WriteLine(csvLine);

                } while (csvLine != null);
            }
        }
    }
}

我認為您的應用程序邏輯有問題。 我的意思是研究狀態機 ,使您的應用程序進入不同的狀態。 因此,在處理數據時,將產生一個正在運行的任務,並會在特定任務完成時發出通知。

您可以使用JS來不時詢問服務器上的狀態,只有在任務完成后才能發送它。

另外,請確保在發送結果的大數據時最后使用壓縮 (這也可能有助於節省內存)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM