Send Generated Pdf as Email Attachment Asp.NetCore

孤者浪人 提交于 2021-01-28 22:07:06

问题


I am using Rotativa to convert my view to pdf. I would like to send that generated pdf as an email attachment (without having to download it first to disk). I've been following a bunch of tutorials to do this but I just keep going round in circles. I would much appreciate any help I can get.

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();

Edit

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,

        ...
    }
   }
    };

回答1:


Complete answer using Rotativa.AspNetCore. Code is developed in VS 2019, Core 3.1, Rotativa.AspNetCore 1.1.1.

Nuget

Install-package Rotativa.AspNetCore

Sample controller

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();
    }
}

Options class

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

In Startup#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"
  }
}



回答2:


There's not quite enough to go on, but you need something like this:

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);
}

Notice this adds the attachment before calling .ToMessageBody(), as well as fixing at least four basic typos.

But I doubt this will be enough... I suspect ViewAsPdf() needs more context than you get from a single DownloadData() request, and you'll need to go back to the drawing board to be able to provide that context, but this at least will help push you in the right direction.



来源:https://stackoverflow.com/questions/63432392/send-generated-pdf-as-email-attachment-asp-netcore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!