我有一个托管在IIS(依赖于框架)上的ASP.NET Core 2.1应用程序,该应用程序使用Rotativa.AspNetCore生成PDF文件。该服务器已安装“用于Windows的.NET Core 2.2运行时和主机捆绑包(v2.2.3)”。
这在本地工作正常,但是当在IIS中部署和托管时,返回的文件似乎不完整(IIS日志sc字节小于应有的字节数),并且浏览器无法显示PDF文件(Chrome显示“错误/无法加载PDF文档。”,Firefox显示“连接已重置”,邮递员显示“无法获得任何响应”。
===更新===
有趣的是,托管在不同服务器上的实时站点没有出现相同的问题,托管在同一服务器上的另一个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文件也无法正确运行,而不仅仅是生成的文件。
我想念什么?启动中是否需要配置一些内容才能成功提供PDF文件?
答案 0 :(得分:1)
save to disk and redirecting to the file
<-这个!您绝对不应让用户浏览您的文件系统。如果他导航到myurl.com/_generated../../web.config或获取您的配置文件怎么办?您绝对应该使用流代替。喜欢:
response.Content = new StreamContent(new FileStream(pathToFile,FileMode.Open));
答案 1 :(得分:0)
事实证明,仅使用 HTTPS 而不是HTTP后,PDF文件便开始可靠地提供服务。
有点掌心的瞬间...