如何使用一个控制器方法返回FileResult和View

时间:2017-08-21 14:20:40

标签: javascript c# asp.net-mvc asp.net-mvc-5

我有一个按钮,通过在控制器中运行保存功能来保存表单。该控制器的格式为:

[HttpPost]
public ActionResult Save(ViewModel model)
{
   Save(model);
   var newModel = new ViewModel();
   return View(Index, newModel); 
}

我有一个表格

的DownloadFile函数
public FileResult DownloadReceipt(int reportId)
{
   filebytes = CreateFile(reportid);
   return File(filebytes, MediaTypeNames.Application.Pdf, "file name");
}

我希望能够允许用户使用第二个函数下载此文件,同时使用第一个函数将用户重定向到索引。单击保存按钮时将调用第一个函数。是否有方便的方法使用该按钮将文件下载到用户计算机上,同时仍然重定向到所需的视图。目前,下载文件功能不会在任何地方调用。

1 个答案:

答案 0 :(得分:0)

控制器操作后面有一个名为HTTP的协议。此协议为每个请求指定应该是单个响应。因此,在回答您的问题时,不可能将多个页面响应(返回)到单个请求。

但冷静下来,仍有希望。我们可以伪造这种行为。有很多方法可以伪造它。我会告诉你一个:

在您的Index.cshtml中,您可以拨打下载页面的电话:

Index.cshtml:

@if((ViewBag.ReportId as int?) > 0)
{
    <script type="text/javascript">
        var url = "@Url.Action("DownloadReceipt", new { reportId = ViewBag.ReportId })";
        window.open(url, "_blank");
    </script>
}
<!-- the rest of index code -->

如果您将此代码放入页面中,则只要页面加载,它就会在不关闭页面页面的情况下调用第二页(DownloadReceipt)。

要使其成功,您现在需要做的就是在行动中设置ViewBag.ReportId

[HttpPost]
public ActionResult Save(ViewModel model)
{
   Save(model);
   var newModel = new ViewModel();
   ViewBag.ReportId = 5; // Change 5 for some code that get report id.
   return View(Index, newModel); 
}

如果设置了ViewBag.ReportId,则索引页面会在加载后立即调用下载页面,否则(如果未设置ViewBag.ReportId)将不会进行下载调用。