简体   繁体   中英

MVC 5 Controller return PDF file doesn't work

I am trying to create a print PDF file for my project.

Here is my code

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult PrintPdf(SubmitReport model)
    {
        if (model == null)
        {
            throw new ArgumentNullException(nameof(SubmitReport));
        }

        var pdfModel = new PdfViewModel {HeaderImgUrl = AppDomain.CurrentDomain.BaseDirectory + @"Content\logo.jpg"};
        var pdfStream = new MemoryStream(PdfGenerator.PayrollConfirmPdf(pdfModel).ToArray());

        // TODO: what is the name of the pdf file?
        var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");

        return File(pdfStream, "application/pdf", filename);            
    }

It seems everything works fine, but after the function return, nothing happen. I was expecting a PDF file open/download in my local machine. However, no pop-up show up (as if nothing happen).

Any ideas?

Thanks in advance.

Seems that this line messing up:

var pdfStream = new MemoryStream(PdfGenerator.PayrollConfirmPdf(pdfModel).ToArray());

This creates instance of MemoryStream from a byte array, which possibly FileResult starts reading from end of stream instead of beginning.

You can use one of 2 possible solutions below:

1) Convert MemoryStream from PayrollConfirmPdf method as byte array and return the PDF as FileContentResult :

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrintPdf(SubmitReport model)
{
    // other stuff

    byte[] pdfStream;

    using (var stream = new MemoryStream())
    {
        // fill stream content from other source
        stream = PdfGenerator.PayrollConfirmPdf(pdfModel);
        pdfStream = stream.ToArray();
    }

    // TODO: what is the name of the pdf file?
    var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");

    // FileContentResult
    return File(pdfStream, "application/pdf", filename);            
}

2) Return FileStreamResult with Seek method set to beginning of stream:

using (var stream = new MemoryStream())
{
    // fill stream content from other source
    // make sure that PayrollConfirmPdf return MemoryStream here!
    stream = PdfGenerator.PayrollConfirmPdf(pdfModel);

    // add this line when using memory stream
    // alternative 1: stream.Seek(0, 0);
    stream.Seek(0, SeekOrigin.Begin); 

    var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");

    // FileStreamResult
    return File(stream, "application/pdf", filename);
}   

Note that you can use stream.Position = 0; to reset stream position if stream.Seek method doesn't work.

Side note:

Since MemoryStream implements IDisposable , you should use using statement to dispose the stream immediately.

Similar issues:

FileResult with MemoryStream gives empty result .. what's the problem?

Return file for Saving from HttpPost Asp.Net MVC method (if using AJAX POST to download the file)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM