Вернуть PDF в браузер, используя JSON и MVC? - PullRequest
4 голосов
/ 24 мая 2011

У меня есть ссылка следующим образом.

@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 ]

6 голосов
/ 04 июня 2015

Вы не можете использовать AJAX для загрузки файлов, потому что javascript не позволяет вам сохранять загруженный контент. Чтобы обойти это, вам нужно сделать 2 шага .

Первый: сделать запрос HTTP Post, и в действии контроллера мы сохраним содержимое файла в потоке памяти. Второй: в случае успеха сделаем еще один вызов, установив окно .расположение к методу Download Action

В вашем контроллере создайте 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 голос
/ 31 мая 2011

Я чувствую себя обязанным опубликовать свой ответ, так как я ничего не слышал.В итоге я создал форму, включающую скрытый ввод, затем сохранил свой объект json в скрытом вводе и затем отправил форму.На этот раз я получу ввод в виде строки, а не JSON или XML.

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

Спасибо, в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...