将生成的 Pdf 作为电子邮件附件发送 Asp.NetCore

Send Generated Pdf as Email Attachment Asp.NetCore

我正在使用 Rotativa 将我的视图转换为 pdf。我想将生成的 pdf 作为电子邮件附件发送(无需先将其下载到磁盘)。我一直在按照一堆教程来做这件事,但我只是一直在兜圈子。如果能得到任何帮助,我将不胜感激。

public async Task<IActionResult>SomeReport()
{
...
return new ViewAsPdf (report)
}
return view();


MemoryStream memoryStream = new MemoryStream();

MimeMessage msg = new MimeMessage();
MailboxAddress from = new MailboxAddress ("Name", "emailAddress")
msg.From.Add(from);
MailboxAddress to = new MailboxAddress ("Name", "emailAddress")
msg.From.Add(to);
BodyBuilder bd = new BodyBuilder();
bb.HtmlBody ="some text";
bb.Attachments.Add("attachmentName", new MemoryStream());
msg.Body = bb.ToMessageBody();
SmtpClient smtp = new SmtpClient();
smtp.Connect("smtp.gmail.com",465, true);
smtp.Authenticate("emailAddress", "Pwd");
smtp.Send(msg);
smtp.Disconnect(true);
smtp.Dispose();

编辑

Parent View from which Email is sent

@Model MyProject.Models.EntityViewModel 
<a asp-action= "SendPdfMail" asp-controller ="Student" asp-route-id = "@Model.Student.StudentId">Email</a>
 ...


SendPdfMail action in Student Controller
public async Task<IActionResult> SendPdfMail(string id)
{  
  var student = await context.Student. Where(s => s.StudentId == id);
  if (student != null)
  {
   ...
   var viewAsPdf = new ViewAsPdf("MyPdfView", new{route = id})
  {      
           Model = new EntityViewModel(),
            FileName = PdfFileName,

        ...
    }
   }
    };

内容还不够,但您需要这样的东西:

MimeMessage msg = new MimeMessage();
MailboxAddress from = new MailboxAddress ("Name", "emailAddress");
msg.From.Add(from);
MailboxAddress to = new MailboxAddress ("Name", "emailAddress");
msg.To.Add(to);
BodyBuilder bb = new BodyBuilder();
bb.HtmlBody ="some text";
using (var wc = new WebClient())
{
    bb.Attachments.Add("attachmentName",wc.DownloadData("Url for your view goes here"));
}
msg.Body = bb.ToMessageBody();
using (var smtp = new SmtpClient())
{
    smtp.Connect("smtp.gmail.com",465, true);
    smtp.Authenticate("emailAddress", "Pwd");
    smtp.Send(msg);
    smtp.Disconnect(true);
}

请注意,这会在调用 .ToMessageBody() 之前添加附件 ,并修复至少四个基本拼写错误。

但我怀疑这是否足够...我怀疑 ViewAsPdf() 需要的上下文比您从单个 DownloadData() 请求中获得的上下文更多,您需要重新开始能够提供该上下文,但这至少会帮助您朝着正确的方向前进。

使用 Rotativa.AspNetCore 完成答案。代码在 VS 2019, Core 3.1, Rotativa.AspNetCore 1.1.1.

中开发

Nuget

Install-package Rotativa.AspNetCore

示例控制器

public class SendPdfController : ControllerBase
{
    private const string PdfFileName = "test.pdf";

    private readonly SmtpClient _smtpClient;

    public SendPdfController(SmtpClient smtpClient)
    {
        _smtpClient = smtpClient;
    }

    [HttpGet("SendPdfMail")] // https://localhost:5001/SendPdfMail
    public async Task<IActionResult> SendPdfMail()
    {
        using var mailMessage = new MailMessage();
        mailMessage.To.Add(new MailAddress("a@b.c"));
        mailMessage.From = new MailAddress("c@d.e");
        mailMessage.Subject = "mail subject here";

        var viewAsPdf = new ViewAsPdf("view name", <YOUR MODEL HERE>)
        {
            FileName = PdfFileName,
            PageSize = Size.A4,
            PageMargins = { Left = 1, Right = 1 }
        };
        var pdfBytes = await viewAsPdf.BuildFile(ControllerContext);

        using var attachment = new Attachment(new MemoryStream(pdfBytes), PdfFileName);
        mailMessage.Attachments.Add(attachment);

        _smtpClient.Send(mailMessage); // _smtpClient will be disposed by container

        return new OkResult();
    }
}

选项class

public class SmtpOptions
{
    public string Host { get; set; }
    public int Port { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}

在启动#ConfigureServices

services.Configure<SmtpOptions>(Configuration.GetSection("Smtp"));

// SmtpClient is not thread-safe, hence transient
services.AddTransient(provider =>
{
    var smtpOptions = provider.GetService<IOptions<SmtpOptions>>().Value;
    return new SmtpClient(smtpOptions.Host, smtpOptions.Port)
    {
      // Credentials and EnableSsl here when required
    };
});

appsettings.json

{
  "Smtp": {
    "Host": "SMTP HOST HERE",
    "Port": PORT NUMBER HERE,   
    "Username": "USERNAME HERE",
    "Password": "PASSWORD HERE"
  }
}