簡體   English   中英

c# mvc - 下載大文件掛起 web 應用程序

[英]c# mvc - Downloading huge files hangs web application

我有一個功能,允許用戶通過單擊網頁上的文件名從服務器下載文件。 我正在使用 ASP.Net MVC5。 任何大小的下載(嘗試高達 2GB)適用於我當前的實現。 問題是下載大於 200MB 的文件時,Web 應用程序會掛起,直到完成下載。

當前實現:當用戶單擊網格中的 fileName 時,它​​會觸發“DocumentController”中的“Download”ActionMethod,從而從服務器下載文件。

然后我想到了兩種方法來解決上述問題:

方法1 :使用異步功能。 我是異步編程的新手。 如果這是最好的方法,請您更新我下面的代碼以使其行為異步。

 public ActionResult Download(string filePath, string fileName)
    {
        try
        {
            if(!string.IsNullOrEmpty(filePath))
            {
                filePath = Path.Combine(baseUrl, filePath);
                string contentType = MimeMapping.GetMimeMapping(fileName);

                TransmitFile(filePath, fileName);
            }
        }
        catch(Exception ex) { }
        return Content("");
    }

    private void TransmitFile(string fullPath, string outFileName)
    {
        System.IO.Stream iStream = null;

        // Buffer to read 10K bytes in chunk:
        byte[] buffer = new Byte[10000];

        // Length of the file:
        int length;

        // Total bytes to read:
        long dataToRead;

        // Identify the file to download including its path.
        string filepath = fullPath;

        // Identify the file name.
        string filename = System.IO.Path.GetFileName(filepath);

        try
        {
            // Open the file.
            iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
                        System.IO.FileAccess.Read, System.IO.FileShare.Read);


            // Total bytes to read:
            dataToRead = iStream.Length;

            Response.Clear();
            Response.ContentType = MimeMapping.GetMimeMapping(filename);
            Response.AddHeader("content-disposition", "attachment; filename=\"" + outFileName + "\"");
            Response.AddHeader("Content-Length", iStream.Length.ToString());

            // Read the bytes.
            while (dataToRead > 0)
            {
                // Verify that the client is connected.
                if (Response.IsClientConnected)
                {
                    // Read the data in buffer.
                    length = iStream.Read(buffer, 0, 10000);

                    // Write the data to the current output stream.
                    Response.OutputStream.Write(buffer, 0, length);

                    // Flush the data to the output.
                    Response.Flush();

                    buffer = new Byte[10000];
                    dataToRead = dataToRead - length;
                }
                else
                {
                    //prevent infinite loop if user disconnects
                    dataToRead = -1;
                }
            }
        }
        catch (Exception ex)
        {
            throw new ApplicationException(ex.Message);
        }
        finally
        {
            if (iStream != null)
            {
                //Close the file.
                iStream.Close();
            }
            Response.Close();
        }
    }

方法 2 :Ajax 調用“下載”ActionMethod。 這對我來說效果不佳。

function downloadFile() {    
var data = //Gets data object using some action and works fine

$.ajax({
    url: '/Document/IsFileExistOnServer',
    data: { 'filePath': data.path },
    type: 'GET',
    success: function (isFileExist) {
        if (typeof isFileExist != "undefined" && isFileExist != null) {
            if (isFileExist == "true") {
                window.location = '@Url.Action("Download", "Document", new { filePath =' + data.path + ', fileName =' + data.name + ' })';                    
            }
            else {
                alert("File Not found. Cannot download");
            }
        }
    },
    error: function (data) {
        alert("Error occured. Please try again.")
    }
});

}

ajax 調用的問題是,請求下載文件的視圖與另一個控制器 (HomeController) 相關聯,單擊下載時,當前頁面被重定向到這樣的鏈接: http://localhost:59740/Home/詳細信息/@Url.Action(下載,文檔,新建{filePath=2017/05/TestFile.db,fileName=test1Gb.db})

請有人幫助我最好的方法來做到這一點。 提前致謝 !!!

我認為你應該使用這個:

Response.OutputStream.WriteAsync(buffer, 0, length);

而不是這個:

Response.OutputStream.Write(buffer, 0, length);

暫無
暫無

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

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