【问题标题】:ASP.NET Core (on IIS) PDF files missing last bytesASP.NET Core(在 IIS 上)PDF 文件缺少最后一个字节
【发布时间】:2019-05-10 10:16:46
【问题描述】:

我有一个托管在 IIS(框架相关)上的 ASP.NET Core 2.1 应用程序,它使用 Rotativa.AspNetCore 生成 PDF 文件。服务器已安装“.NET Core 2.2 Runtime & Hosting Bundle for Windows (v2.2.3)”。

这在本地运行良好,但在 IIS 中部署和托管时,返回的文件似乎不完整(IIS 日志 sc-bytes 小于应有的值)并且浏览器无法显示 PDF 文件(Chrome 显示“错误 /加载 PDF 文档失败。”,Firefox 显示“连接已重置”,Postman 显示“无法得到任何响应”)。

=== 更新 ===

有趣的是,托管在不同服务器上的实时站点没有显示相同的问题,托管在同一服务器上的另一个 ASP.NET Core 2.1 应用程序也没有。

我终于发现,简单地使用 HTTPS 解决了这个问题,它现在可以可靠地提供文件。

=== 结束更新 ===

调试级别的标准输出日志没有任何有用的信息,事件查看器也没有。看起来服务器认为它成功地处理了请求,但不知何故,在响应成功发送到浏览器之前连接就关闭了。

作为最后的手段,我尝试将生成的文件保存在文件系统上,然后重定向到该文件,但即使这样也有同样的问题。

我的原始代码如下所示:

public IActionResult MyExport()
{
    var myViewModel = new MyViewModel();
    return new ViewAsPdf("~/Views/PdfExport/MyExport.cshtml", myViewModel)
    {
        PageSize = Size.A4,
        PageOrientation = Orientation.Portrait,
        PageMargins = { Left = 1, Right = 1 }
    };
}

尝试保存到磁盘并重定向到文件后,我的代码基本上是这样的:

public async Task<IActionResult> MyExport()
{
    var myViewModel = new MyViewModel();
    var pdf = new ViewAsPdf("~/Views/PdfExport/MyExport.cshtml", myViewModel)
    {
        PageSize = Size.A4,
        PageOrientation = Orientation.Portrait,
        PageMargins = { Left = 1, Right = 1 }
    };
    var pdfBytes = await pdf.BuildFile(ControllerContext);
    var path = $"/_generated/xyz.pdf";
    System.IO.File.WriteAllBytes($"{_hostingEnvironment.WebRootPath}{path}", pdfBytes);
    return Redirect(path);
}

文件在/wwwroot/_generated/xyz.pdf中成功生成,但不知何故即使直接浏览到myurl.com/_generated/xyz.pdf仍然遇到同样的问题,似乎只返回了部分内容。
我有一个示例,其中标头 Content-Length 是 88185 字节,但 IIS 日志中的 sc-bytes 只有 63852 字节

生成的 PDF 文件非常小(例如 87kB),对于任何更大的静态文件(图像、js 等),我都没有遇到过同样的问题。

编辑
即使是上传的 PDF 文件也无法正确提供,而不仅仅是生成的文件。

我错过了什么?我需要配置 Startup 中的某些内容以成功提供 PDF 文件吗?

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    save to disk and redirecting to the file

    response.Content = new StreamContent(new FileStream(pathToFile,FileMode.Open));
    

    【讨论】:

    • 生成的文件保存在wwwroot中,其中还包含图片、css、js等其他静态文件。我看不出这会带来什么额外的安全风险——我没有在Startup.cs 中修改app.UseStaticFiles();。我尝试了FileStreamResultPhysicalFileResult 都得到了相同的结果。如上所述,wwwroot 中的静态 PDF 文件也会出现此问题,浏览器开发工具显示不同的传输大小。
    【解决方案2】:

    事实证明,在简单地使用 HTTPS 而不是 HTTP 之后,PDF 文件开始可靠地提供服务。
    有点拍脸的瞬间……

    【讨论】:

      猜你喜欢
      • 2012-05-23
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      相关资源
      最近更新 更多