2012-01-09 31 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