ASP.NET MVC C#:表单提交后用Rotativa生成PDF并附加至自动邮件
在ASP.NET MVC中用Rotativa生成PDF并附加到确认邮件,同时跳转成功页面
核心问题是一个Action只能返回一个结果,无法同时返回PDF文件和视图页面。解决思路是先在后台生成PDF字节流,将其写入临时文件作为邮件附件发送,最后返回成功视图,具体实现如下:
完整实现代码
public ActionResult ProcessOrder(int? id) { if (!id.HasValue) { return RedirectToAction("Index"); } // 1. 获取订单详情(根据你的业务逻辑从数据库/数据源读取) var orderDetail = db.OrderDetails.FirstOrDefault(o => o.OrderID == id.Value); if (orderDetail == null) { return HttpNotFound(); } string orderPdfFileName = $"FulfillmentOrder{orderDetail.OrderID}.pdf"; byte[] pdfContent = null; string tempPdfPath = string.Empty; string errorMessage = string.Empty; try { // 2. 使用Rotativa生成PDF字节流(不直接返回,而是自行处理内容) var pdfGenerator = new ActionAsPdf("OrderReportPDF", new { id = orderDetail.OrderID }) { FileName = orderPdfFileName }; pdfContent = pdfGenerator.BuildFile(ControllerContext); // 3. 将PDF字节流写入临时文件(WebMail.Send需要文件路径作为附件) tempPdfPath = Path.Combine(Path.GetTempPath(), orderPdfFileName); System.IO.File.WriteAllBytes(tempPdfPath, pdfContent); // 4. 发送带附件的确认邮件 var emailSubject = $"Order Confirmation #{orderDetail.OrderID}"; var recipientEmail = "john.doe@example.com"; // 替换为实际用户邮箱 var emailBody = "Your order has been placed and is pending review. Attached is a copy of your order."; // 初始化SMTP配置(根据你的实际邮件服务器调整) WebMail.SmtpServer = "abc.net"; WebMail.SmtpPort = 555; WebMail.UserName = "your-smtp-username@samplecode.com"; // 注意:这里应该是SMTP服务器的认证账号,不是收件人 WebMail.Password = "your-smtp-password"; WebMail.From = "orders@samplecode.com"; // 发送邮件 WebMail.Send( to: recipientEmail, subject: emailSubject, body: emailBody, filesToAttach: new[] { tempPdfPath } ); } catch (Exception ex) { errorMessage = ex.Message; // 可选:记录错误日志,或者返回错误提示视图 } finally { // 5. 清理临时PDF文件,避免磁盘空间浪费 if (!string.IsNullOrEmpty(tempPdfPath) && System.IO.File.Exists(tempPdfPath)) { try { System.IO.File.Delete(tempPdfPath); } catch { /* 忽略删除失败的情况,比如文件被临时占用 */ } } } // 6. 清除购物车会话并返回成功页面 Session.Remove("strCart"); // 替换为你实际的购物车会话键 return View("OrderSuccess"); }
关键说明
使用BuildFile方法生成字节流:
Rotativa的ActionAsPdf提供了BuildFile方法,传入当前ControllerContext即可生成PDF的字节数组,这样就不需要返回ActionAsPdf对象,而是可以自行处理生成的内容。临时文件处理:
因为WebMail.Send的filesToAttach参数只能接收文件路径,所以我们把PDF字节流写入系统临时目录的文件中,邮件发送完成后在finally块中删除该文件,避免磁盘堆积。SMTP配置注意:
你原代码中WebMail.UserName使用了收件人邮箱,这通常是错误的——这里应该填写SMTP服务器的认证账号(比如发件人邮箱的账号),请根据你的邮件服务提供商的配置调整。权限问题:
部署到IIS时,确保应用程序池身份有写入系统临时目录的权限,否则无法创建临时PDF文件。
内容的提问来源于stack exchange,提问作者Kip M.
相关产品推荐
相关产品推荐

