2012-01-09 66 views
1

我有一個控制器有兩個頁面,索引和下載,當點擊下載它從服務中檢索一個字節[],我用Response.BinaryWrite保存文件。與此問題是,使用Response.Clear時,它會停止呈現下載頁面,但成功下載文件。有什麼方法可以下載文件並渲染頁面?如何:從web服務保存文件,而不停止頁面呈現

我使用.NET 4,ASP,單軌城堡,C#

我意識到,通過使用MVC我能夠使用的ActionResult和FileResult作爲返回類型我的看法,我不過限於使用單軌城堡是因爲它是我最近擁有的一個現有項目,在改變它的技術方面沒有任何重量。

下面是我的示例代碼

public class MyController : Controller 
{ 
    public void Index() 
    { 
     PropertyBag["includeZeroBalances"] = false; 
     PropertyBag["toDate"] = DateTime.Today.ToShortDateString(); 
    } 

    public void Download(bool includeZeroBalances, DateTime toDate) 
    { 
     MyProxy proxy = GetProxy(); 
     byte[] file = proxy.GetFile(includeZeroBalance, toDate); 
     Response.Clear(); 
     Response.ContentType = "application/zip"; 
     Response.AppendHeader("Content-Disposition", "attachment; filename="TestFileName.zip"); 
     Response.BinaryWrite(file); 
    } 
} 

這裏是索引頁

${Form.FormTag({@action: 'Download'})} 
    <table> 
     <tr> 
      <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td> 
      <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td> 
     </tr> 
     <tr> 
      <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td> 
      <td>${Form.CheckboxField("includeZeroBalances")}</td> 
     </tr> 
     <tr> 
      <td>&nbsp;</td> 
      <td>${Form.Submit("Download", {@class: 'submitb'})}</td> 
     </tr> 
    </table> 
${Form.EndFormTag()} 

這裏是下載頁面

<table> 
    <tr> 
     <td>Your file has been downloaded successfully</td> 
    </tr> 
</table> 

回答

1

我想出了答案並不像一般的,我也喜歡,但這種解決方案的功能。

public class MyController : Controller 
{ 
    public void Index() 
    { 
     PropertyBag["includeZeroBalances"] = false; 
     PropertyBag["toDate"] = DateTime.Today.ToShortDateString(); 
    } 

    public void Download(bool includeZeroBalances, DateTime toDate) 
    { 
     MyProxy proxy = GetProxy(); 
     byte[] file = proxy.GetFile(includeZeroBalance, toDate); 
     PropertyBag["downloadurl"] = "data:application/zip;base64," + System.Convert.ToBase64String(file); 
    } 
} 

這裏是索引頁

${Form.FormTag({@action: 'Download'})} 
    <table> 
     <tr> 
      <td>${Form.LabelFor("toDate", "To Date (yyyy/mm/dd):")}</td> 
      <td><input type="text" id="toDate" name="toDate" value="${?toDate}" /></td> 
     </tr> 
     <tr> 
      <td>${Form.LabelFor("includeZeroBalances", "Include Zero Balances:")}</td> 
      <td>${Form.CheckboxField("includeZeroBalances")}</td> 
     </tr> 
     <tr> 
      <td>&nbsp;</td> 
      <td>${Form.Submit("Download", {@class: 'submitb'})}</td> 
     </tr> 
    </table> 
${Form.EndFormTag()} 

這裏是下載頁面

<table> 
    <tr> 
     <td>Your file has been generated successfully. <a href="${downloadurl}">Click here</a> to download your file</td> 
    </tr> 
</table> 

您還可以添加JavaScript來自動下載文件中的一個新窗口。使用這種方法來保存文件的

document.Ready(function() 
{ 
    window.open("${downloadurl}"); 
}); 

優點: 沒有文件保存在服務器上。 在大約300kb下載文件時開銷略低 您不覆蓋響應數據,因此視圖將按照正常情況進行渲染。

使用此方法保存文件的缺點: 不適用於任何版本的任何瀏覽器。 如果用於靜態文件,當文件更改時,由於文件內容嵌入在uri中,所以uri將不得不再次生成。我希望這可以幫助其他似乎一直困擾在同一問題上的其他人。我在許多電路板上看到過這種類型的問題,並沒有直接的解決方案。

1

'正確' 的方式做,這將是使用多部分響應,不幸的是some browsers don't support them

你可以做的是使用像sourceforge和其他網站的元刷新。替代方案,看到這些問題:

+0

嗨Mauricio,謝謝你提供的鏈接和見解。不幸的是,這並不完全是我所期待的。 – 2012-01-10 14:18:07

+0

@ROFFELPOMP:恩,這正是你在答案中所做的。 – 2012-01-10 14:39:30