2009-12-31 32 views
0

我目前正在從控制器生成一個相當大的文件,並從一個視圖中單擊按鈕返回。 我想要做的是在生成文件時顯示一個覆蓋層,聲明「生成文件」,一旦完成覆蓋層消失。 我將如何去做這樣的事情?在從控制器生成/返回文件的同時顯示覆蓋圖

下面是我的控制器的樣子。

public ActionResult Generate(FormViewModel fvm) 
    { 
     var isValid = AreInputsValid(fvm); 
     if (!isValid) 
     { 
      TryUpdateModel(fvm); 
      return View("Index",); 
     } 
     RenderReport(new Report(fvm)); 
     return View(); 
    } 

    private void RenderReport(Models.Report report) 
    { 
     var localReport = new LocalReport { ReportPath = report.ReportPath }; 

     var reportDataSource = new ReportDataSource(report.DataSourceName, report.Model); 
     localReport.DataSources.Add(reportDataSource); 

     var reportType = "PDF"; 
     string mimeType; 
     string encoding; 
     string fileNameExtension; 

     //The DeviceInfo settings should be changed based on the reportType 
     //http://msdn2.microsoft.com/en-us/library/ms155397.aspx 
     var deviceInfo = 
      string.Format("<DeviceInfo><OutputFormat>{0}</OutputFormat><PageWidth>11in</PageWidth><PageHeight>8.5in</PageHeight><MarginTop>0.5in</MarginTop><MarginLeft>0.25in</MarginLeft><MarginRight>0.25in</MarginRight><MarginBottom>0.5in</MarginBottom></DeviceInfo>", reportType); 

     Warning[] warnings; 
     string[] streams; 

     //Render the report 
     var renderedBytes = localReport.Render(
      reportType, 
      deviceInfo, 
      out mimeType, 
      out encoding, 
      out fileNameExtension, 
      out streams, 
      out warnings); 

     //Clear the response stream and write the bytes to the outputstream 
     //Set content-disposition to "attachment" so that user is prompted to take an action 
     //on the file (open or save) 
     Response.Clear(); 
     Response.ContentType = mimeType; 
     Response.AddHeader("content-disposition", "attachment; filename=" + report.ReportName + "." + fileNameExtension); 
     Response.BinaryWrite(renderedBytes); 
     Response.End(); 
    } 

在此先感謝

+0

我試過了,但是一旦文件被返回,頁面仍然顯示div。我試過調用$ .unblockUI();當你從服務器回來時 – 2009-12-31 17:12:50

+0

我編輯了我的答案給出了更多的信息 – 2009-12-31 17:33:07

回答

1

我會使用jQuery的blockUI顯示疊加在一個div有你「生成文件」的消息。你可以彈出這onClientClick,它會一直保持,直到你從服務器回來

我總是把這塊代碼放在我使用blockUI的頁面上 這是有幫助的,當由於某種原因你必須從服務器回來並顯示一個模態,否則會隱藏先前可見的模態。

function pageLoad(event, args) 
{ 
    var hdf = $('[id$=hdf_DisplayModal]').val(); 

    if(hdf != "") 
     showPopup(hdf); 
    else 
     $.unblockUI(); 
} 

然後我有一個附加包含以下內容的外部jasvascript文件:

function showPopup(modal) 
{ 
    showPopup(modal, null); 
} 

function showPopup(modal, fadeInTime) 
{ 
    if(fadeInTime == null) 
     fadeInTime = 500; 

    modal = $('[id$=' + modal + ']'); 
    $.blockUI({ message: modal, 
     fadeIn : fadeInTime, 
     css: { 
      top: ($(window).height() - modal.height())/2 + 'px', 
      left: ($(window).width() - modal.width()) /2 + 'px', 
      width: modal.width() + 'px' 
     } 
    }); 
} 

function closePopup(modal) 
{ 
    closePopup(modal, null); 
} 

function closePopup(modal, fadeOutTime) 
{ 
    $('[id$=hdf_DisplayModal]').attr("value", ""); 
    modal = $('[id$=' + modal + ']') 
    $.unblockUI({ message: modal, 
     fadeOut: fadeOutTime 
    }); 
} 

現在,我從來沒有做過任何這在MVC,但是從我的同事聽到所有這些都應該可以在稍微調整之後進行。我希望它有幫助。

+0

我試過了,我會使用控制器的代碼更新我的文章,也許會有幫助p – zSynopsis 2009-12-31 16:42:30

1

這裏的用戶界面是你的問題最少的。

如果您有一個需要多秒執行的操作,那麼您正在綁定ASP.NET工作線程來壓縮站點的可伸縮性。這是爲什麼MVC 2 has AsyncControllers for delegating long-running tasks to a background thread。還有a workaround for MVC 1。您的行爲不應寫入Response。這樣做會使操作變得不必要地難以測試,並且偏離標準MVC管道,其中像ViewResult這樣的結果對象對Response進行實際寫入。

最後,當您準備好更新UI​​時,通常會使用回調來執行此操作。

例如,先從「在原始查看加載消息:

<div id="report">Loading...</div> 

然後在準備好時加載,並更換‘正在加載...’與響應的內容:

$(document).ready(function() { 
    $("#report").load("/path/to/action"); 
}); 
+0

對不起,我仍然不明白。如果寫入響應流是一個否定的,那麼你會如何推薦我去返回生成的文件?我是mvc的新手,所以任何幫助將不勝感激。 – zSynopsis 2009-12-31 17:52:47

+0

一種方法是編寫自定義結果類型。這裏有一個示例:http://haacked.com/archive/2008/05/10/writing-a-custom-file-download-action-result-for-asp.net-mvc.aspx總的想法是,操作將數據傳遞給結果,並且結果更新響應。 – 2009-12-31 18:06:52