You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC C#:同控制器内如何在方法中调用另一个Action

解决方案:在控制器中生成Rotativa PDF并作为邮件附件发送

直接调用AttachFile方法返回的ActionAsPdf无法直接作为文件路径传给WebMail.Send,因为ActionAsPdf是MVC用于向客户端返回PDF的ActionResult,不会自动生成磁盘文件。你需要先将PDF生成字节流,保存到临时文件后再作为附件发送。

步骤1:重构PDF生成逻辑

将生成PDF的逻辑提取为返回字节数组的私有方法,方便在任意Action中调用:

private byte[] GenerateOrderPdf(int? id)
{
    if (!id.HasValue)
        throw new ArgumentNullException(nameof(id));
        
    string orderFileName = $"FulfillmentOrder{id}.pdf";
    var pdfGenerator = new ActionAsPdf("OrderDetailsReport", new { id = id }) 
    { 
        FileName = orderFileName 
    };
    
    // 生成PDF字节流
    return pdfGenerator.BuildPdf(ControllerContext);
}

步骤2:修改ProcessOrder Action

在订单处理方法中调用上述方法生成PDF,保存到临时文件,发送邮件后清理临时文件:

public ActionResult ProcessOrder(int? id)
{
    if (!id.HasValue)
        return BadRequest("Order ID is required");
        
    // 补充:从数据库或数据源获取订单详情
    var orderDetail = /* 你的订单数据获取逻辑,例如 db.OrderDetails.Find(id) */;
    if (orderDetail == null)
        return NotFound("Order not found");
        
    var msgTitle = $"Order Confirmation #{orderDetail.OrderID}";
    var recipient = "JohnDoe@yourdomain.com"; // 替换为实际收件人邮箱
    string tempPdfPath = null;
    var errorMessage = string.Empty;
    var orderConfirmationContent = "Your order has been placed and is pending review." +
                                  " Attached is a copy of your order.";
                
    try
    {
        // 生成PDF字节流并保存到临时文件
        var pdfBytes = GenerateOrderPdf(id);
        tempPdfPath = Path.Combine(Path.GetTempPath(), $"FulfillmentOrder{id}.pdf");
        File.WriteAllBytes(tempPdfPath, pdfBytes);

        // 初始化邮件配置
        WebMail.SmtpServer = "abc.net";
        WebMail.SmtpPort = 555;
        WebMail.UserName = recipient;
        WebMail.Password = "12345";
        WebMail.From = "orders@samplecode.com";

        // 发送带附件的邮件
        WebMail.Send(
            to: "orders@samplecode.com",
            subject: msgTitle,
            body: orderConfirmationContent,
            filesToAttach: new[] { tempPdfPath }
        );
    }
    catch (Exception ex)
    {
        errorMessage = ex.Message;
        // 可添加日志记录逻辑
    }
    finally
    {
        // 清理临时文件,避免磁盘占用
        if (!string.IsNullOrEmpty(tempPdfPath) && File.Exists(tempPdfPath))
        {
            try
            {
                File.Delete(tempPdfPath);
            }
            catch { /* 忽略删除失败的情况,避免影响主流程 */ }
        }
    }

    // 补充:返回合适的结果,例如重定向到订单状态页或返回视图
    return View();
}

关键说明

  1. BuildPdf方法:Rotativa的ActionAsPdf提供了BuildPdf方法,传入当前控制器的ControllerContext即可直接生成PDF字节流,无需通过HTTP请求调用Action。
  2. 临时文件处理:使用系统临时目录保存PDF,发送邮件后及时删除,避免磁盘空间浪费。
  3. 参数校验:添加了ID非空和订单存在的校验,提升代码健壮性。

内容的提问来源于stack exchange,提问作者Kip M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:55:18