使用JSON和MVC将PDF返回给浏览器?

时间:2011-05-23 21:28:26

标签: asp.net-mvc json pdf

我的链接如下。

@Html.ActionLink("Create Report", "Screenreport", "Reports", null, new { @class = "subNavA AddBorderTop", id = "screenReport", title = "Create Report" })

点击链接后,我有一个以下jQuery代码,它创建一个JSON对象并发布信息。

$().ready(function () {

   // Create Report fron the screen data
   $("#screenReport").live("click", function (event) { GenerateScreenReport(this, event); });

}) /* end document.ready() */

function GenerateScreenReport(clikedtag, event) {

   var table = $(".EvrakTable").html();
   var screendata = tableParser(table);
   var Screentable = { Screenlist: screendata };

   var myurl = $(clikedtag).attr("href");
   var title = $(clikedtag).attr("title");


   $.ajax({ 
      url: myurl,
      type: 'POST',
      data: JSON.stringify(Screentable),
      dataType: 'json',
      contentType: 'application/json',
      success: function () { alert("Got it"); }
   }); 

};

要处理JSON我有以下两个类。在同一名称空间中实现两个类

namespace MyProject.ViewModels
{
   public class Screenrecord
   {
      public string Fname{ get; set; }
      public string LName { get; set; }
      public string Age { get; set; }
      public string DOB { get; set; }
   }


   public class Screentable
   {
      public List<Screenrecord> Screenlist { get; set; } 
   }
}

在我的控制器中,我有以下代码:

   [HttpPost]
   public FileStreamResult Screenreport(Screentable screendata)
   {
      MemoryStream outputStream = new MemoryStream();
      MemoryStream workStream = new MemoryStream();
      Document document = new Document();
      PdfWriter.GetInstance(document, workStream);
      document.Open();
      document.Add(new Paragraph("Hello World"));
      document.Add(new Paragraph(DateTime.Now.ToString()));
      document.Close();

      byte[] byteInfo = workStream.ToArray();
      outputStream.Write(byteInfo, 0, byteInfo.Length);
      outputStream.Position = 0;

      return new FileStreamResult(outputStream, "application/pdf");

   }

此代码应该是PDF格式。 如果我按原样离开[HttpPost],它不会生成PDF并且它会进入/ Screenreport页面,但是我看到我的JSON正确传递给控制器​​。 (screendata填充正确 - 在控制器中)

但如果我注释掉[HttpPost],它会生成PDF但screendata(在控制器中)为空。

有人可以解释一下这是怎么回事并帮助我解决问题。提前致谢。

2 个答案:

答案 0 :(得分:6)

您无法使用AJAX下载文件,因为javascript不允许您保存下载的内容。 要解决此问题,您需要执行 2个步骤

首先:发出HTTP Post请求,在控制器操作中,我们将文件内容存储在内存流中。第二次成功通过设置进行另一次调用window.location到Download Action方法

在你的Controller中创建这2个动作:

public ActionResult GenerateFile()
    {
        MemoryStream fileStream = new MemoryStream { Position = 0 };
        //position = 0 is important

        var fName = string.Format("File-{0}.xlsx", DateTime.Now.ToString("s"));
        Session[fName] = fileStream;
        return Json(new { success = true, fName }, JsonRequestBehavior.AllowGet);
    }
    public ActionResult DownloadFile(string fName)
    {
        var ms = Session[fName] as MemoryStream;
        if (ms == null)
            return new EmptyResult();
        Session[fName] = null;
        return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fName);
    }

在你的javascript中:

$('#Donwload-button').click(function () {
    data = JSON.stringify(YOURDATA);
    $.ajax({
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        url: "/YOURCONTROLLER/GenerateFile",
        data: data,
        success: function (d) {
            if (d.success) {
                window.location = "/YOURCONTROLLER/DownloadFile" + "?fName=" + d.fName;
            }
        },
        error: function () {
           alert("Error");
        }
    });

});

答案 1 :(得分:1)

我觉得有义务发布我的回答,因为我没有收到任何人的回复。我最终创建了一个包含隐藏输入的表单,然后将我的json对象保存在隐藏的输入中,然后提交表单。这次我将输入作为字符串而不是json或xml。

var $hidInput = $("#dataToReport"); 
$hidInput.val(JSON.stringify(Screentable)); 
$('#frmScreenreport').submit(); 

非常感谢。