簡體   English   中英

如何從MVC4中的異步動作重定向到另一個動作

[英]How can I redirect to another action from my Asynchronous Action in MVC4

我目前正在嘗試編寫一些代碼,這些代碼將接受一些FTP詳細信息,獲取文件列表,然后允許用戶下載文件。

一切正常,除了我必須等待文件完成下載之后才能執行任何操作。 我正在使用異步控制器,因為我認為這旨在幫助解決此類問題。

請在下面查看我的代碼選擇,我遺漏了所有與代碼無關的代碼:

  [HttpPost]
    public ActionResult FtpAsync(Downloads model)
    {
        var ftpAddress = model.Url;
        if (!ftpAddress.StartsWith("ftp://"))
            ftpAddress = String.Concat("ftp://", ftpAddress);

        var serverPath = Server.MapPath(ThumbnailSupport.CreateBaseVirtualPathForClient(StandardFileLinks.DropBoxLocation,
                                                                        _website.Client));

        if (!Directory.Exists(serverPath))
            Directory.CreateDirectory(serverPath);

        foreach (string file in model.SelectedFiles)
        {

            var webClient = new WebClient();

            AsyncManager.OutstandingOperations.Increment();

            AsyncManager.Parameters["FilesToDownload"] = model.SelectedFiles;
            webClient.Credentials = new NetworkCredential(model.Username, model.Password);

            webClient.DownloadFileAsync(new Uri(ftpAddress + "/" + file), serverPath + "\\" + file);
            AsyncManager.OutstandingOperations.Decrement();
        }

        return RedirectToAction("Transfer");

    }


    public ActionResult FtpCompleted(Downloads model)
    {
        return RedirectToAction("Complete");
    }

    public ActionResult Transfer()
    {
        return PartialView();
    }

它可以很好地觸發FtpCompleted操作,但是問題是這意味着要處理潛在GB信息的文件傳輸。 我不希望用戶在等待文件下載時坐下來觀看旋轉的光盤。 因此,我嘗試將他們重定向到“轉移操作”的原因是,該操作僅顯示一條消息,告訴他們轉移可能需要一段時間,一旦轉移完成,就會通知他們。 但是,此操作實際上從未被調用。 我逐步調試了代​​碼,並對其進行了調用,但是根據FireBug的說法,它從不顯示消息,也不會到達瀏覽器。

我是在做一些愚蠢的事情,還是只是做不到?

我會很感激人們在這里可以提供的任何幫助,因為在瀏覽google和此處的其他帖子后,我完全陷入了困境。 即使是經驗豐富的編碼員,我的老板也不確定該如何處理。

提前致謝,

加茲

文檔中所述,異步控制器操作包含2種方法:

  1. 一種返回void並具有Async后綴和操作名稱前綴的方法
  2. 返回ActionResult並具有Completed后綴和操作名稱前綴的方法

第一種方法觸發異步操作並立即返回。 整個操作完成后,將調用第二種方法。

所以這是正確的動作簽名:

[HttpPost]
public void FtpAsync(Downloads model)
{
    ...
}

public ActionResult FtpCompleted(Downloads model)
{
    return Content("Complete");
}    

現在,如果您不想在整個操作過程中凍結瀏覽器,則必須使用AJAX調用第一個控制器操作。 異步控制器不會根據HTTP協議進行任何更改。 從客戶的角度來看,這是絕對相同的。 與標准控制器操作的唯一區別是,在整個操作過程中,您不會危害工作線程。 現在,您依賴IOCP(IO /完成端口),它是WebClient使用的OS工件。 這個想法是,當您開始進行IO密集型操作時,將創建IOCP端口,並且控制器操作會立即將線程返回到ASP.NET線程池。 然后該操作可能持續數小時,一旦完成IOCP信號,就會從線程池中提取一個池,並在該線程上調用Completed操作。 因此在線程方面非常有效。 但是執行的總時間與使用標准控制器操作絕對相同。 許多人認為,由於異步控制器被稱為異步,因此它們從客戶端角度異步運行。 這是一個錯誤的印象。 異步操作不會使您的操作奇跡般地運行得更快。 從客戶端的角度來看,它們仍然是完全同步的,因為這就是HTTP協議的工作方式。

因此,您有2種可能性:

  • 使用AJAX調用控制器操作,以避免阻塞瀏覽器。
  • 使用COMET / PUSH技術,在該技術中,服務器將通知客戶端。 例如,在HTML5中,可以使用WebSockets標准來實現這一目標。 在.NET世界中, SignalR是一個很好的框架,它封裝了該PUSH技術。

如果您想要一個真正有效的解決方案,則建議使用第二種方法。

暫無
暫無

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

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