MVC 5控制器返回PDF文件不起作用

时间:2018-04-26 01:28:26

标签: c# asp.net-mvc pdf

我正在尝试为我的项目创建一个打印PDF文件。

这是我的代码

    [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);            
    }

似乎一切正常,但在函数返回后,什么都没发生。我期待在我的本地机器上打开/下载PDF文件。但是,没有弹出窗口(好像什么也没发生)。

有什么想法吗?

提前致谢。

1 个答案:

答案 0 :(得分:2)

似乎这条线搞砸了:

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

这会从字节数组中创建MemoryStream的实例,可能FileResult从流的末尾开始读取而不是开始读取。

您可以使用以下两种可能的解决方案之一:

1)将MemoryStream方法中的PayrollConfirmPdf转换为字节数组,并将PDF作为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)将FileStreamResult方法设置为流的开头返回Seek

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);
}   

请注意,如果stream.Position = 0;方法不起作用,您可以使用stream.Seek重置流位置。

旁注:

由于MemoryStream实现IDisposable,您应该使用using语句立即处理流。

类似问题:

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

Return file for Saving from HttpPost Asp.Net MVC method(如果使用AJAX POST下载文件)