1

I have created an ASP.NET MVC web app in which I accept some information from the client via an AJAX post and create a pdf using iTextSharp. On returning a response to the client, I would like the browser to automatically download the pdf on the user's computer. I began by actually saving the file to a folder and returning the absolute path, so I know the code generates the pdf successfully. Instead of returning the actual path, though, I have read that I can instead store it in a MemoryStream and put that in my response. I have tried returning the actual MemoryStream, converting it to a byte array and returning that, returning a FileStreamResult, and adding the MemoryStream to the Response, but nothing seems to be working. I know similar questions have been asked, but none of the code I have found seems to solve my problem. Can someone please tell me what I need to change in my code to accomplish this, please?

AJAX code:

.ajax({
    url: "/Reports/GenShoppingList",
    type: "Post",
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(recipeIdArray),
    datatype: "application/pdf"
 });

Pdf Creation and Response code:

public static void GenShoppingListPDF(StringBuilder ingredientNames)
{
    MemoryStream MemoryStream = new MemoryStream();
    doc = new Document();
    PdfWriter.GetInstance(doc, MemoryStream).CloseStream = false;
    doc.Open();
    doc.Add(new Paragraph(ingredientNames.ToString()));
    doc.Close();
    string fileName = "ShoppingList-" + DateTime.Now.ToString() + ".pdf";
    HttpResponse response = HttpContext.Current.Response;
    response.Clear();
    response.ContentType = "application/pdf";
    response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
    response.BinaryWrite(MemoryStream.ToArray());
    response.Flush();
    response.Close();
    response.End();
}

The StringBuilder object is passed into the code via a controller action that simply creates the object and calls this static method. The controller action return type is void.

Final Solution: Through further research and discussion, I have concluded that JQuery AJAX does not support posting data and returning a pdf. Rather, it is best to simply use a plain XMLHttpRequest and forego using JQUERY.

  • What error are you getting? Or how is the code not working? – mroach Feb 26 '17 at 15:31
  • 1
    I believe this [SO answer](http://stackoverflow.com/a/779500/1453651) and [this one](http://stackoverflow.com/a/1675026/1453651) may be helpful to you. Also, look into using the FileResult class it is really useful and you can even make a custom PDFFileResult class that can have the content type and addheader logic embedded so you DRY if you need to use it everyewhere [e.g.](https://cprakash.com/2012/11/19/a-simple-pdfresult-in-mvc-3/). – Judge Bread Feb 26 '17 at 21:33
  • @mroach There are no exceptions being thrown, but the file is not automatically triggering a download of the pdf. I can use a success: function(result){ alert(success.toString()); }, and it will display what I believe is supposed to be the byte[] info of the Response. – David Garrett Feb 26 '17 at 22:33
  • @JudgeBread The first option is simply using a different dll, and I would like to use iTextSharp if at all possible. Others have used it with success, so I don't see why I can't get it to work in the end. I have already tried the second post without success. I am thinking it has something to do with my AJAX call or the fact that I am using a [HttpPost] data annotation. Would either of those make sense in your mind? – David Garrett Feb 27 '17 at 01:47
  • Hi David, both links are for iTextSharp so I don't know what you mean by different dll's - do you mean different versions? Secondly, the HttpPost should not pose a problem. What I see is posing the issue is jquery's ajax call. While thoroughly searching for it I see numerous people in the same boat as you doing it with hacks. Search jquery ajax pdf download. A better solution is having a hidden form on the page. Fill it with your ingredientnames and post that with [jquery](https://api.jquery.com/submit/). Then the response of the form submission will trigger the download. Could you try it? – Judge Bread Feb 27 '17 at 07:21
  • If I'm understanding you correctly, it seems you're suggesting I already have the ingredients on the client side in a hidden form. When I submit the form, won't I be in the same situation I'm already in? I'm able to get the input from the ajax call to the server and create the pdf. The difficulty is with sending it back and triggering an automatic download. Is this what you suggested, or am I misunderstanding you? I've already searched "jquery ajax pdf download," but another search won't hurt. I'll get it another go now. – David Garrett Feb 28 '17 at 00:17

2 Answers2

0

Look with the library you are using this works for me and download the file correctly.

public ActionResult File()
{
  string ingredientNames = "Hello David";
  using (MemoryStream stream = new MemoryStream())
  {
    var doc = new Document();
    PdfWriter.GetInstance(doc, stream).CloseStream = false;

    doc.Open();
    doc.Add(new Paragraph(ingredientNames.ToString()));
    doc.Close();

    return File(stream.ToArray(), System.Net.Mime.MediaTypeNames.Application.Pdf, "file.pdf");
  }
}
Dei Revoledo
  • 175
  • 1
  • 5
  • Perhaps the error is coming from the ajax call then? I used the code you proposed, but it did not result in an automatic download. Does an AJAX call require me to return something to it to use? Another thing that may be catching me up is the [HttpPost] data annotation on my action. What do you think? – David Garrett Feb 27 '17 at 01:41
  • OHHHHHH I understand you now. You can open this url in a new link in the browser and the browser download for you. var url='http://localhost:1000/Home/File'; window.open(url, 'Download'); – Dei Revoledo Feb 27 '17 at 13:45
  • What url would I pass in as a parameter? The file is being passed directly from the server. – David Garrett Feb 28 '17 at 00:10
0

Final Solution: Through further research and discussion, I have concluded that JQuery AJAX does not support posting data and returning a pdf. Rather, it is best to simply use a plain XMLHttpRequest and forego using JQUERY.