【问题标题】:Save Controller Call Result as PDF将控制器调用结果保存为 PDF
【发布时间】:2013-05-07 10:36:15
【问题描述】:

我正在开发一个 ASP.NET MVC3 应用程序。我有一个文件下载控制器:

public ActionResult PDF(string id)
{
    try
    {
        // here I unzip a file, DownName comes from here

        Response.Clear();
        Response.AddHeader("Content-Disposition", 
                           "attachment; filename=" + id + ".pdf");
        Response.ContentType = "application/pdf";
        Response.WriteFile(DownName);
        Response.Flush();
        Response.Close();
        System.IO.File.Delete(DownName);
        return View();
    }
    catch (Exception)
    {
        message = "File not found.";
    }

    return Json(new { message = message }, JsonRequestBehavior.AllowGet);
}

在客户端,我需要获取此 PDF 文件。但是,如果找不到文件,我会提示“找不到文件”之类的文本。我尝试了很多方法,最终得出了这个结论:

$(function(){
  $(".pdf").click(function(e) {
    e.preventDefault();
    $.post("@Url.Action("PDF","Helper")",{id : $(this).data("id")},function(data){
      if(data.message == "File not found.") {
        alert(data.message);
      } else {
        alert(data);
      }
    });
  });
});

如果找不到文件,我可以成功警告错误消息。如何在此处打开数据的保存对话框?我也可以为控制器工作的任何其他方式表示赞赏。

编辑:如果我这样调用控制器,我可以轻松下载文件:

<a href="../../Helper/PDF/@Model.ID">Download PDF</a>

但是,如果结果不是文件和 JSON,页面将被重定向到显示 JSON 对象的空白页面。正如我之前所说,我希望它对屏幕保持警惕。我也很欣赏这种方法的变通方法。

【问题讨论】:

    标签: jquery json asp.net-mvc-3


    【解决方案1】:

    您必须从您的操作中返回一个 FileResult。否则,您将无法告诉浏览器下载文件。 当通过 javascript 异步请求请求文件数据时,您无法触发浏览器将该数据保存到本地文件。

    当您必须能够检查文件是否存在时,您必须提供两个操作:

    public JsonResult PDFAvailable(string id) {
        // check if the file is there
        return Json(new { message = message }, JsonRequestBehavior.AllowGet);
    }
    
    public FileResult PDF(string id) {
        // get the filedata
        byte[] fileData = ...;
        return File(fileData, "application/pdf");
    }
    

    在您看来,您使用 PDFAvailable 操作 id 检查文件是否存在。如果它不显示您的消息,则使用正常请求调用 PDF 操作:

    window.location.href = 
         '@Url.Action("PDF", "YourController", new { id = "yourFileId" })';
    

    编辑

    关于您的 chrome 问题并设置 location.href:这在 chrome 中绝对有效。做个测试:创建一个html文件,内容如下:

    <script>
        location.href = "http://www.google.com";
    </script>
    

    并在 chrome 中打开它。它应该将您的浏览器重定向到谷歌主页。当它发生时,您的代码还有其他问题。如果没有,请告诉我您使用的是哪个版本的 chrome。

    【讨论】:

    • 谢谢,但是将 alert(data) 更改为 location.href = '@Url.Action("PDF", "Helper", new { id = Model.ID })'; 有效。但是,即使我添加了return false 语句,它在 Chrome 中也不起作用。
    • @IsmetAlkan 你在 Chrome 的那一行收到一个 javascript 错误吗?它也应该在 chrome 中工作——没什么特别的。我在我的网络应用程序中使用了一种非常相似的方法,它适用于所有浏览器。
    • 我没有收到任何具体错误,只是没有响应。您可以根据我在问题中所做的编辑您的答案,因为您的答案指导了我,但它并不完全正确。
    • @IsmetAlkan 我已经编辑了我的答案。但是 location.href 肯定在 chrome 中工作。自己试过了。
    • 我写了谷歌链接而不是Url.Action,它也没有用。我的 chrome 版本是 26.0.1410.64 m。
    猜你喜欢
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    相关资源
    最近更新 更多