生成PDF并返回IActionResult本地正常部署后报HTTP500
问题描述
我开发了一个功能,通过代码生成PDF后以IActionResult返回展示。本地运行时一切正常,控制器能成功打开PDF;但发布部署到托管环境后,访问同一URL出现HTTP 500错误,无法下载或显示PDF。我怀疑是IIS权限问题,已经联系托管方但还没得到有效处理。相关代码如下:
控制器代码
public IActionResult downloadLabels() { try { var printdate = DateTime.Now; var uname = HttpContext.User.FindFirst(ClaimTypes.Name).Value; var labels = _context.Labels .Where(w => w.Status == "Print") .Include(i => i.OrderNavigation) .ToList(); if (labels.Count > 0) { return Json("buldun"); string webRootPath = _hostingEnvironment.WebRootPath; string directoryPath = Path.Combine(webRootPath); string fileName = DateTime.Now.ToString().Replace(".", "-").Replace(":", "-") + "_" + uname + "_labels.pdf"; string filePath = Path.Combine(directoryPath, fileName); using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { int pagenumber = 1; Document document = new Document(); //string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); PdfWriter writer = PdfWriter.GetInstance(document, fileStream); //PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(@"C:\Users\abdul\Desktop\" + uname + "_labels.pdf", FileMode.Create)); document.Open(); int check = 1; foreach (var label in labels) { var lblcnt = _context.Labels.Where(w => w.OrderId == label.OrderId).ToList().Count(); if (label.Platform != "Walmart") { byte[] bytes = Convert.FromBase64String(label.Image.Split(",")[1]); Image img = Image.GetInstance(bytes); img.ScaleToFit(document.PageSize.Width - document.LeftMargin - document.RightMargin, document.PageSize.Height - document.TopMargin - document.BottomMargin); document.NewPage(); document.Add(img); if (check == lblcnt) { document.NewPage(); var pageNumberPhrase = new Phrase(pagenumber.ToString()); pageNumberPhrase.Font = FontFactory.GetFont(FontFactory.HELVETICA, 10, Font.BOLD); var pageNumberParagraph = new Paragraph(pageNumberPhrase); pageNumberParagraph.Alignment = Element.ALIGN_CENTER; document.Add(pageNumberParagraph); iTextSharp.text.pdf.draw.LineSeparator line = new iTextSharp.text.pdf.draw.LineSeparator { LineWidth = 1, LineColor = BaseColor.BLACK }; document.Add(new Chunk("\n")); document.Add(new Paragraph(label.OrderNavigation.Address, FontFactory.GetFont(FontFactory.HELVETICA, 18))); document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); var barcodeWriter = new ZXing.Windows.Compatibility.BarcodeWriter { Format = BarcodeFormat.CODE_128, Options = new ZXing.Common.EncodingOptions { Height = 130, Width = 600, NoPadding = true, } }; var barcodeImage = barcodeWriter.Write(label.OrderNavigation.OrderNumber); // Convert the barcode image to bitmap var barcodeBitmap = new System.Drawing.Bitmap(barcodeImage); iTextSharp.text.Image barcodeImg = iTextSharp.text.Image.GetInstance(barcodeBitmap, System.Drawing.Imaging.ImageFormat.Bmp); document.Add(barcodeImg); //var myBarcode = BarcodeWriter.CreateBarcode(label.OrderNavigation.OrderNumber, BarcodeWriterEncoding.Code128); //myBarcode.ResizeTo(500, 100); //myBarcode.AddBarcodeValueTextBelowBarcode(); //var barbytes = myBarcode.ToPngBinaryData(); //Image imgb = Image.GetInstance(barbytes); //document.Add(imgb); var items = labels.Where(w => w.OrderId == label.OrderId).GroupBy(g => g.Title).Select(s => s.First()).ToList(); foreach (var item in items) { document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph(label.Title, FontFactory.GetFont(FontFactory.HELVETICA, 18))); document.Add(new Chunk("x" + label.OrderNavigation.Quantity.ToString(), FontFactory.GetFont(FontFactory.HELVETICA, 30))); document.Add(new Chunk("\n")); document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph("SKU: " + label.Sku, FontFactory.GetFont(FontFactory.HELVETICA, 16))); } document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph("Label Count: " + lblcnt.ToString(), FontFactory.GetFont(FontFactory.HELVETICA, 18))); pagenumber++; check = 1;; } else { check++; } } else { byte[] bytes = Convert.FromBase64String(label.Image); PdfReader reader = new PdfReader(bytes); for (int i = 1; i <= reader.NumberOfPages; i++) { PdfImportedPage page = writer.GetImportedPage(reader, i); document.NewPage(); Rectangle pageSize = reader.GetPageSizeWithRotation(i); float scaleX = (document.PageSize.Width - document.LeftMargin - document.RightMargin) / pageSize.Width; float scaleY = (document.PageSize.Height - document.TopMargin - document.BottomMargin) / pageSize.Height; float scale = Math.Min(scaleX, scaleY); float offsetX = (document.PageSize.Width - (pageSize.Width * scale)) / 2; float offsetY = (document.PageSize.Height - (pageSize.Height * scale)) / 2; PdfContentByte contentByte = writer.DirectContent; contentByte.AddTemplate(page, scale, 0, 0, scale, offsetX, offsetY); } if (check == lblcnt) { document.NewPage(); iTextSharp.text.pdf.draw.LineSeparator line = new iTextSharp.text.pdf.draw.LineSeparator { LineWidth = 1, LineColor = BaseColor.BLACK }; var pageNumberPhrase = new Phrase(pagenumber.ToString()); pageNumberPhrase.Font = FontFactory.GetFont(FontFactory.HELVETICA, 10, Font.BOLD); var pageNumberParagraph = new Paragraph(pageNumberPhrase); pageNumberParagraph.Alignment = Element.ALIGN_CENTER; document.Add(pageNumberParagraph); document.Add(new Chunk("\n")); document.Add(new Paragraph(label.OrderNavigation.Address, FontFactory.GetFont(FontFactory.HELVETICA, 18))); document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); var barcodeWriter = new ZXing.Windows.Compatibility.BarcodeWriter { Format = BarcodeFormat.CODE_128, Options = new ZXing.Common.EncodingOptions { Height = 130, Width = 600, NoPadding = true, } }; var barcodeImage = barcodeWriter.Write(label.OrderNavigation.OrderNumber); // Convert the barcode image to bitmap var barcodeBitmap = new System.Drawing.Bitmap(barcodeImage); iTextSharp.text.Image barcodeImg = iTextSharp.text.Image.GetInstance(barcodeBitmap, System.Drawing.Imaging.ImageFormat.Bmp); document.Add(barcodeImg); var items = labels.Where(w => w.OrderId == label.OrderId).GroupBy(g => g.Title).Select(s => s.First()).ToList(); foreach (var item in items) { document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph(label.Title, FontFactory.GetFont(FontFactory.HELVETICA, 18))); document.Add(new Chunk("x" + label.OrderNavigation.Quantity.ToString(), FontFactory.GetFont(FontFactory.HELVETICA, 30))); document.Add(new Chunk("\n")); document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph("SKU: " + label.Sku, FontFactory.GetFont(FontFactory.HELVETICA, 16))); } document.Add(new Chunk("\n")); document.Add(line); document.Add(new Chunk("\n")); document.Add(new Paragraph("Label Count: " + lblcnt.ToString(), FontFactory.GetFont(FontFactory.HELVETICA, 18))); pagenumber++; check = 1; } else { check++; } } if(uname != "admin") { label.Status = "Labeled"; label.PrintDate = printdate; _context.SaveChanges(); } } document.Close(); byte[] fileBytes = System.IO.File.ReadAllBytes(filePath); //Response.Headers["Content-Disposition"] = "inline;filename=" + fileName; //Response.ContentType = "application/pdf"; return File(fileBytes, "application/pdf",fileName); } } return Json("No Labels to Print"); } catch (Exception e) { return Json(e.Message.ToString()); } }
路由代码
<li class="nav-item"> <a class="nav-link" onclick="downloadLabels()"> <i class="fa-file-pdf"></i>Get Labels </a> </li> <script> function downloadLabels() { window.open("/Amazon/downloadLabels", "_blank"); } </script>
解决方案
1. 修复致命逻辑错误
你代码里有个严重逻辑问题:在if (labels.Count > 0)分支第一行就是return Json("buldun");,这会直接终止方法,后续生成PDF的代码完全不会执行。本地测试正常大概率是你注释过这行,部署时没处理,赶紧删掉这行无效代码。
2. 绕开IIS权限问题(推荐方案)
直接用内存流生成PDF,完全避免磁盘写入操作,彻底解决权限问题:
// 替换原文件流逻辑为内存流 using (var ms = new MemoryStream()) { Document document = new Document(); PdfWriter writer = PdfWriter.GetInstance(document, ms); // 后续生成PDF的所有逻辑保持不变... document.Close(); ms.Position = 0; // 重置流指针到开头 return File(ms.ToArray(), "application/pdf", fileName); }
3. 若必须写入磁盘的处理方式
- 在应用根目录创建专门的
TempPdf文件夹,给IIS应用池账号(通常是IIS AppPool\你的应用池名称)分配读写权限 - 确保目录存在再写入:
string directoryPath = Path.Combine(_hostingEnvironment.ContentRootPath, "TempPdf"); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } string filePath = Path.Combine(directoryPath, fileName);
4. 捕获详细错误信息
当前catch块只返回异常消息,无法定位具体问题,修改为返回完整异常信息:
catch (Exception e) { return Json(new { Message = e.Message, StackTrace = e.StackTrace, InnerException = e.InnerException?.Message }); }
部署后访问接口,就能看到具体是哪一步出错(权限不足、依赖缺失等)。
5. 其他排查点
- 确认托管环境已安装
System.Drawing.Common依赖(.NET Core/5+非Windows环境需额外配置) - 检查
ZXing.Windows.Compatibility包是否在部署环境正常加载
内容的提问来源于stack exchange,提问作者aoiTenshi
相关产品推荐
相关产品推荐

