【问题标题】:No download dialog with FileResultFileResult 没有下载对话框
【发布时间】:2011-01-30 12:03:40
【问题描述】:

我正在从表单发布事件触发的操作中返回文件结果。 我无法获得下载对话框。相反,如果我使用:

return File(Encoding.UTF8.GetBytes(reportPath), "text/plain", "Report.csv");

我在目标 div 中执行 ajax 时获得文件的路径。

当我使用时

return File(reportPath, "text/plain", "Report.csv");

我在目标 div 中获取文件的内容。

动作被声明为

   [HttpPost]
   public virtual ActionResult ExportFilter(Model model) {
      string outputFile = CreateReport(model);
      return File(....)
   }

表单是通过 Ajax.BeginForm(...) 提交的。

编辑

更多信息:我的表单有 2 个提交按钮。一个用于在目标 div 中呈现结果,另一个用于导出结果。 actton 是相同的,我用它来确定哪个按钮触发了事件:

        [HttpPost]
        public virtual ActionResult Run( model )
        {
            var bExecute = !string.IsNullOrEmpty(Request.Form["execute"]);
            return bExecute ? Execute(model) : Export(model);
        }

        [HttpPost]
        public virtual ActionResult Execute( model )
        {
            ....
            return PartialView("Report", model); 
        }

       [HttpPost]
       public virtual FileResult Export( model ) {
                .....
               return File(....)
       }

经过一些回答后,我尝试使用以下命令重定向到 Get 操作:

   ....
    return RedirectToAction( MVC.Report.OfferDownload(ReportFile) );
}

    [HttpGet]
    public virtual FileResult OfferDownload(string FileName)
    {
        return File(FileName, "text/csv", "Report.csv");
    }

然而,这并没有帮助。

我也尝试过流式传输文件,但也没有用。

EDIT2

肯定是 Ajax 问题,因为当我将 Ajax.BeginForm 替换为 Html.BeginForm 时它会起作用。我想到的一种解决方案是在提交按钮上使用 onclick 事件来更改表单属性。

【问题讨论】:

  • 我认为主要问题是 AJAX 提交 - 请参阅我更新的答案。
  • 您应该在 POST 请求后重定向用户并让该方法为文件提供服务。发布/重定向/获取。您还应该明确地将您的操作方法的返回类型设为 FileResult。

标签: .net asp.net-mvc


【解决方案1】:

打开位于服务器上提供的路径的文件并读取其内容。将内容作为 FileResult 向下发送。此外,如果您希望下载,请不要通过 AJAX 提交表单。响应将被发送到 AJAX 代码,我认为浏览器不会拦截它并给你一个文件下载对话框。这实际上可能是整个问题(在这种情况下,您的第二个样本可能会起作用)。

 string outputFile = CreateReport(model);
 using (var stream = new StreamReader( outputFile ))
 {
    return File( stream, "text/csv", "Report.csv" );
 }

编辑:FWIW,我会为 CSV 文件使用“text/csv”或“application/csv”。

【讨论】:

  • 不通过 Ajax 提交表单对我来说不是一个选项。你看,表单的排列方式是它有 2 个提交按钮 - 1 个通过 ajax 在目标 div 中显示结果,另一个导出结果
  • 我可能会做的是让导出按钮的单击处理程序执行正常提交(非 AJAX),而另一个按钮执行 AJAX 提交。我什至可能会对出口采取单独的行动。事实上,当我这样做时,我通常有一个操作来处​​理任何过滤器参数并将过滤器参数存储在会话中。那就是“表单”在过滤器上——它通过 AJAX 发布并更新显示。此时导出成为一个简单的链接,并使用过滤器参数(或默认值)来获取适当的数据并将其作为文件发送。
【解决方案2】:

对于遇到此问题的任何新人:在 POST 方法中重定向到 GET 将不起作用。您可以保留您的 Ajax POST,并且在其成功后,您可以通过 FileResult GET 操作方法执行 GET 以提供文件以供下载。

$.ajax({
    url: '@Url.Action("ExportFilter")',
    type: 'POST',
    cache: false,
    async: true,
    success: function (data) {
            window.location.replace(urlOfferDownload + "?FileName=" + data.FileName);
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2020-08-29
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    相关资源
    最近更新 更多