.NET Core 2.0 MVC:如何链接文件系统中的动态PDF文件
一步步解决你的PDF文件访问问题
我来帮你搞定这个需求,核心思路是通过控制器中转来访问根目录外的文件,再把视图里的路径换成可点击的链接就行:
1. 给控制器加个文件中转动作
因为你的PDF存在网站根目录外,没法直接通过静态文件访问,所以得在你的业务控制器(比如HomeController或者专门的FileController)里加一个动作,负责安全读取并返回文件:
public IActionResult GetPDF(string filePath) { // 重点!一定要加路径校验,防止恶意访问服务器其他文件 // 先定义你允许访问的外部文件根目录,比如存在项目上级的PDFFiles文件夹 var allowedRoot = Path.Combine(Environment.ContentRootPath, "../PDFFiles"); var fullFilePath = Path.GetFullPath(filePath); // 校验请求的路径是否在允许的根目录范围内 if (!fullFilePath.StartsWith(allowedRoot, StringComparison.OrdinalIgnoreCase)) { return Forbid(); // 非法请求直接拒绝 } // 文件不存在就返回404 if (!System.IO.File.Exists(fullFilePath)) { return NotFound("指定的PDF文件不存在"); } // 用FileStream返回,大文件也不会占太多内存 var fileStream = new FileStream(fullFilePath, FileMode.Open, FileAccess.Read); // 这里设置返回类型为application/pdf,浏览器会直接打开;如果要默认下载,改成application/octet-stream return File(fileStream, "application/pdf", Path.GetFileName(fullFilePath)); }
划重点:路径校验绝对不能省!不然攻击者可能通过构造
filePath参数来遍历服务器上的敏感文件,比如系统配置、其他用户数据之类的,风险很高。
2. 修改Details视图,把路径换成可点击的链接
把你原来显示@Model.PDF的地方,换成指向上面这个动作的链接就行,用ASP.NET Core的标签助手生成URL更方便:
<!-- 原来的代码:@Model.PDF --> <!-- 替换成下面的可点击链接 --> <a asp-action="GetPDF" asp-controller="你的控制器名称" asp-route-filePath="@Model.PDF">查看/下载PDF</a>
比如你的控制器叫DocumentController,那asp-controller就填Document。
额外优化小技巧
- 把允许的文件目录配置到
appsettings.json里,后期改路径不用改代码:
然后在控制器里通过"AppSettings": { "AllowedPDFRoot": "../PDFFiles" }IConfiguration注入读取这个值,比硬编码灵活多了。 - 如果想让链接默认触发下载,就在控制器的
File方法里调整返回类型,或者指定FileDownloadName:return File(fileStream, "application/octet-stream", Path.GetFileName(fullFilePath));
内容的提问来源于stack exchange,提问作者user6383418
相关产品推荐
相关产品推荐

