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,
...
}
}
};
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"
}
}
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.
Related
I want to have one API call send to a list of recipients and customize each email. I have the general code worked out. The substitutions are working. But this only sends to the first email address even though I have 2 personalizations with different email addresses.
SendGridClient client = new SendGridClient(apiKey);
SendGridMessage msg = new SendGridMessage();
msg.SetFrom(new EmailAddress(from, fromName));
msg.Subject = subject;
msg.HtmlContent = some content with replacement fields
List<string> recipients = new List<string>();
recipients.Add("some address");
recipients.Add("second address");
msg.Personalizations = new List<Personalization>();
for (int x = 0; x < recipients.Count; x++) {
if (recipients[x].IndexOf("#") > -1) {
//msg.AddTo(recipients[x]);
Personalization personalization = new Personalization();
personalization.Tos = new List<EmailAddress> { new EmailAddress(recipients[x]) };
Dictionary<string, string> subs = new Dictionary<string, string>();
subs.Add("[Verification Code]", "ABC123");
subs.Add("[User Name]", "Mark");
personalization.Substitutions = subs;
msg.Personalizations.Add(personalization);
addressAdded = true;
}
}
Response response = await client.SendEmailAsync(msg).ConfigureAwait(false);
What am I doing wrong? Is there some documentation on this?
IsValidEmail Method:
public static bool IsValidEmail(string email)
{
try
{
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}
SendEmail Method:
SendGridClient client = new SendGridClient(apiKey);
SendGridMessage msg = new SendGridMessage();
msg.SetFrom(new EmailAddress(from, fromName));
msg.Subject = subject;
msg.HtmlContent = "<strong> C# is the Best! </strong>";
List<string> recipients = new List<string>();
recipients.Add("some address");
recipients.Add("second address");
msg.Personalizations = new List<Personalization>();
foreach (string recipient in recipients)
{
if (IsValidEmail(recipient))
{
Personalization personalization = new Personalization();
personalization.Tos = new List<EmailAddress>();
personalization.Tos.Add(new EmailAddress(recipient));
msg.Personalizations.Add(personalization);
Dictionary<string, string> subs = new Dictionary<string, string>();
subs.Add("{{UserName}}", "Mark");
subs.Add("{{VerificationCode}}","ABC123");
personalization.Substitutions = subs;
msg.Personalizations.Add(personalization);
addressAdded = true;
}
// This Worked
if (addressAdded)
{
Response response = await client.SendEmailAsync(msg);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Headers.ToString());
Console.WriteLine(response.Body.ReadAsStringAsync().Result);
}
}
I am using NetCore.MailKit NuGet package to help me send an email which contains a link to confirm their email when the user registers. I have followed the steps on their Github page but, I am getting an ArgumentNullException for the address, even though I have set the sending address.
The error:
ArgumentNullException: Value cannot be null. (Parameter 'address')
MimeKit.MailboxAddress..ctor(Encoding encoding, string name, string address)
The above error occurs when is send the email in my controller using IEmailService:
_EmailService.Send("usersemail#gmail.com", "subject", "message body");
This is my appsettings.json configuration:
"EmailConfiguration": {
"Server": "smtp.gmail.com",
"Port": 587,
"SenderName": "name",
"SenderEmail": "mygmail#gmail.com",
"SenderPassword": "My gmail password"
}
This is my setup in startup.cs
services.AddMailKit(optionBuilder =>
{
optionBuilder.UseMailKit(new MailKitOptions()
{
//get options from sercets.json
Server = Configuration["Server"],
Port = Convert.ToInt32(Configuration["Port"]),
SenderName = Configuration["SenderName"],
SenderEmail = Configuration["SenderEmail"],
Account = Configuration["SenderEmail"],
Password = Configuration["SenderPassword"],
Security = true
});
});
Below is the code for EmailService:
public void Send(string mailTo, string subject, string message, bool isHtml = false)
{
SendEmail(mailTo, null, null, subject, message, Encoding.UTF8, isHtml);
}
private void SendEmail(string mailTo, string mailCc, string mailBcc, string subject, string message, Encoding encoding, bool isHtml)
{
var _to = new string[0];
var _cc = new string[0];
var _bcc = new string[0];
if (!string.IsNullOrEmpty(mailTo))
_to = mailTo.Split(',').Select(x => x.Trim()).ToArray();
if (!string.IsNullOrEmpty(mailCc))
_cc = mailCc.Split(',').Select(x => x.Trim()).ToArray();
if (!string.IsNullOrEmpty(mailBcc))
_bcc = mailBcc.Split(',').Select(x => x.Trim()).ToArray();
Check.Argument.IsNotEmpty(_to, nameof(mailTo));
Check.Argument.IsNotEmpty(message, nameof(message));
var mimeMessage = new MimeMessage();
//add mail from
mimeMessage.From.Add(new MailboxAddress(_MailKitProvider.Options.SenderName, _MailKitProvider.Options.SenderEmail));
//add mail to
foreach (var to in _to)
{
mimeMessage.To.Add(MailboxAddress.Parse(to));
}
//add mail cc
foreach (var cc in _cc)
{
mimeMessage.Cc.Add(MailboxAddress.Parse(cc));
}
//add mail bcc
foreach (var bcc in _bcc)
{
mimeMessage.Bcc.Add(MailboxAddress.Parse(bcc));
}
//add subject
mimeMessage.Subject = subject;
//add email body
TextPart body = null;
if (isHtml)
{
body = new TextPart(TextFormat.Html);
}
else
{
body = new TextPart(TextFormat.Text);
}
//set email encoding
body.SetText(encoding, message);
//set email body
mimeMessage.Body = body;
using (var client = _MailKitProvider.SmtpClient)
{
client.Send(mimeMessage);
}
}
As you can see I have set everything, am I missing something here? why is address null at MimeKit.MailboxAddress()?
You seem to be not loading your configuration settings correctly. I suspect the failing line in your code is
//add mail from
mimeMessage.From.Add(new MailboxAddress(_MailKitProvider.Options.SenderName, _MailKitProvider.Options.SenderEmail));
The Options are all null, which causes the exception.
When you load the settings from a configuration file you need to prepend the section name to the variables. E.G.
services.AddMailKit(optionBuilder =>
{
optionBuilder.UseMailKit(new MailKitOptions()
{
//get options from sercets.json
Server = Configuration["EmailConfiguration:Server"],
Port = Convert.ToInt32(Configuration["EmailConfiguration:Port"]),
SenderName = Configuration["EmailConfiguration:SenderName"],
SenderEmail = Configuration["EmailConfiguration:SenderEmail"],
Account = Configuration["EmailConfiguration:SenderEmail"],
Password = Configuration["EmailConfiguration:SenderPassword"],
Security = true
});
});
My guess is that the exception is being thrown on the following line:
mimeMessage.From.Add(new MailboxAddress(_MailKitProvider.Options.SenderName, _MailKitProvider.Options.SenderEmail));
This means that _MailKitProvider.Options.SenderEmail is null.
I know you expect these values to be loaded correctly from your appsettings.json file, but seemingly, they are not being loaded for some reason.
After sending an email the logo is not displayed in Outlook but it works in Gmail.
I found that in the inspect element that the image src is changed into blockedimagesrc
In my Controller :
var NotifyCompany = new NotifyCompany()
{
Email = model.regE,
EmailTo = contact.GetPropertyValue<string>("email"),
DateRegistered = DateTime.UtcNow
};
EmailHelpers.SendEmail(NotifyCompany, "NotifyCompany", "New Client Registered");
Helpers :
public static ActionResponse SendEmail(IEmail model, string emailTemplate, string subject, List<HttpPostedFileBase> files = null)
{
try
{
var template =
System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath(string.Format("~/Templates/{0}.cshtml", emailTemplate)));
var body = Razor.Parse(template, model);
var attachments = new List<Attachment>();
if (files != null && files.Any())
{
foreach (var file in files)
{
var att = new Attachment(file.InputStream, file.FileName);
attachments.Add(att);
}
}
var email = Email
.From(ConfigurationManager.AppSettings["Email:From"], "myWebsiteEmail")
.To(model.EmailTo)
.Subject(subject)
.Attach(attachments)
.Body(body).BodyAsHtml();
email.Send();
return new ActionResponse()
{
Success = true
};
}
catch (Exception ex)
{
return new ActionResponse()
{
Success = false,
ErrorMessage = ex.Message
};
}
}
In my Email Template :
<img src="/mysite.com/image/logo.png"/>
Any help would be appreciated.
Outlook web access will block any images by default - only if the user chooses to display/download images these will be displayed/downloaded. I am not sure if it is possible to adjust the default behavior by using office 365 admincenter or the OWA settings.
Some time ago it was possible to work around this by using it as a background image inside a table>tr>td cell background-image css property.
EDIT
Checked a recent project of myself, where we are sending notification mails about tickets. The site logo is displayed correctly in outlook/owa - without adding the recipient to the trusted list:
using (MailMessage mm = new MailMessage(sender, header.RecipientAddress, header.Subject, header.Body))
{
mm.Body = header.Body;
mm.BodyEncoding = Encoding.UTF8;
mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
mm.Priority = priority == IntMailPriority.High ? MailPriority.High : MailPriority.Normal;
mm.IsBodyHtml = bodyIsHtml;
// logo
if (bodyIsHtml)
{
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(header.Body, Encoding.UTF8, "text/html");
string logoPath = $"{AppDomain.CurrentDomain.BaseDirectory}\\images\\logo_XXX.png";
LinkedResource siteLogo = new LinkedResource(logoPath)
{
ContentId = "logoId"
};
htmlView.LinkedResources.Add(siteLogo);
mm.AlternateViews.Add(htmlView);
}
// create smtpclient
SmtpClient smtpClient = new SmtpClient(smtpSettings.ServerAddress, smtpSettings.Port)
{
Timeout = 30000,
DeliveryMethod = SmtpDeliveryMethod.Network
};
// set relevant smtpclient settings
if (smtpSettings.UseTlsSsl)
{
smtpClient.EnableSsl = true;
// needed for invalid certificates
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
}
if (smtpSettings.UseAuth)
{
smtpClient.UseDefaultCredentials = false;
NetworkCredential smtpAuth = new NetworkCredential { UserName = smtpSettings.Username, Password = smtpSettings.Password };
smtpClient.Credentials = smtpAuth;
}
smtpClient.Timeout = smtpSettings.SendingTimeout * 1000;
// finally sent mail \o/ :)
try
{
smtpClient.Send(mm);
}
catch (SmtpException exc)
{
throw new ProgramException(exc, exc.Message);
}
catch (InvalidOperationException exc)
{
throw new ProgramException(exc, exc.Message);
}
catch (AuthenticationException exc)
{
throw new ProgramException(exc, exc.Message);
}
}
Afterwards the logo is referred to as
<IMG alt="Intex Logo" src="cid:logoId">
inside the generated html.
I'm trying to set up an IMAP server which is pulling data from a SQL database.
I've got the messages working no problems, but I can't work out how to attach attachments to them.
The attachments object on the Mail_Message object also only has a getter and a method called GetAttachments() which doesn't seem to connect to anywhere.
My current code is:
//this is my own object I'm using to pull data from the database
var cmMsg = _ml.GetMessage(mId, session.AuthenticatedUserIdentity.Name, -1);
var msgBody = new MIME_b_Text(MIME_MediaTypes.Text.html);
var msg = new Mail_Message();
msg.Body = msgBody;
msg.To = new Mail_t_AddressList();
msg.From = new Mail_t_MailboxList {new Mail_t_Mailbox(cmMsg.From, cmMsg.FromEmail)};
msg.Cc = new Mail_t_AddressList();
msg.Bcc = new Mail_t_AddressList();
foreach (var recipient in cmMsg.Recipients)
{
if (recipient.isTo)
{
msg.To.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
else if(recipient.isCC)
{
msg.Cc.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
else if (recipient.isBCC)
{
msg.Bcc.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
}
//I tried adding a setter to the attachment object, but just get errors with this code
var a = new List<MIME_Entity>();
foreach (var attachment in cmMsg.Attachments)
{
var aCT = new MIME_b_Multipart(new MIME_h_ContentType("application/octet-stream"));
a.Add(new MIME_Entity
{
Body = aCT,
ContentDisposition = new MIME_h_ContentDisposition("attachment"),
});
}
msg.Attachments = a.ToArray();
msg.Subject = cmMsg.Subject;
msg.Date = cmMsg.TimeDate;
msg.MessageID = cmMsg.InternetMessageId;
if (e.FetchDataType == IMAP_Fetch_DataType.MessageStructure)
{
}
else if(e.FetchDataType == IMAP_Fetch_DataType.MessageHeader)
{
}
else
{
msgBody.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, cmMsg.HtmlBody);
_da.MarkAsRead(archiveID, session.AuthenticatedUserIdentity.Name);
}
e.AddData(info, msg);
I'm not sure if I'm missing something or just got this set up wrong. I noticed there was a MySQL API in the example projects, but that didn't have anything to do with attachments in it either.
Ok so turns out I was going about it the complete wrong way. Below is the code required
Effectively, it requires setting the message to be multipart mixes instead of just text. You can then add the attachments as a body part.
var cmMsg = _ml.GetMessage(mId, session.AuthenticatedUserIdentity.Name, -1);
MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
var msg = new Mail_Message();
msg.To = new Mail_t_AddressList();
msg.From = new Mail_t_MailboxList {new Mail_t_Mailbox(cmMsg.From, cmMsg.FromEmail)};
msg.Cc = new Mail_t_AddressList();
msg.Bcc = new Mail_t_AddressList();
msg.Body = multipartMixed;
foreach (var recipient in cmMsg.Recipients)
{
if (recipient.isTo)
{
msg.To.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
else if(recipient.isCC)
{
msg.Cc.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
else if (recipient.isBCC)
{
msg.Bcc.Add(new Mail_t_Mailbox(recipient.FullName, recipient.SMTPAddress));
}
}
msg.Subject = cmMsg.Subject;
msg.Date = cmMsg.TimeDate;
msg.MessageID = cmMsg.InternetMessageId;
msg.MimeVersion = "1.0";
msg.Header.Add(new MIME_h_Unstructured("X-MS-Has-Attach", "yes"));
if (e.FetchDataType == IMAP_Fetch_DataType.MessageStructure)
{
}
else if(e.FetchDataType == IMAP_Fetch_DataType.MessageHeader)
{
}
else
{
MIME_Entity entity_text_plain = new MIME_Entity();
MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
entity_text_plain.Body = text_plain;
text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, cmMsg.HtmlBody);
multipartMixed.BodyParts.Add(entity_text_plain);
foreach (var attachment in cmMsg.Attachments)
{
using (var fs = new FileStream(#"C:\test.txt", FileMode.Open))
{
multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(fs, "test.txt"));
}
}
}
e.AddData(info, msg);
I'm going through my app, trying to clean up some code that sends e-mails. I started creating my own emailer wrapper class, but then I figured that there must be a standard emailer class out there somewhere. I've done some searching, but couldn't find anything.
Also, is there a code base for stuff like this anywhere?
EDIT: Sorry, let me clarify.
I don't want to have this in my code any time I need to send an e-mail:
System.Web.Mail.MailMessage message=new System.Web.Mail.MailMessage();
message.From="from e-mail";
message.To="to e-mail";
message.Subject="Message Subject";
message.Body="Message Body";
System.Web.Mail.SmtpMail.SmtpServer="SMTP Server Address";
System.Web.Mail.SmtpMail.Send(message);
I created a class named Emailer, that contains functions like:
SendEmail(string to, string from, string body)
SendEmail(string to, string from, string body, bool isHtml)
And so I can just put this a single line in my code to send an e-mail:
Emailer.SendEmail("name#site.com", "name2#site.com", "My e-mail", false);
I mean, it's not too complex, but I figured there was a standard, accepted solution out there.
Something like this?
using System;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using MailMessage=System.Net.Mail.MailMessage;
class CTEmailSender
{
string MailSmtpHost { get; set; }
int MailSmtpPort { get; set; }
string MailSmtpUsername { get; set; }
string MailSmtpPassword { get; set; }
string MailFrom { get; set; }
public bool SendEmail(string to, string subject, string body)
{
MailMessage mail = new MailMessage(MailFrom, to, subject, body);
var alternameView = AlternateView.CreateAlternateViewFromString(body, new ContentType("text/html"));
mail.AlternateViews.Add(alternameView);
var smtpClient = new SmtpClient(MailSmtpHost, MailSmtpPort);
smtpClient.Credentials = new NetworkCredential(MailSmtpUsername, MailSmtpPassword);
try
{
smtpClient.Send(mail);
}
catch (Exception e)
{
//Log error here
return false;
}
return true;
}
}
Maybe you're looking for SmtpClient?
I use a generic class made out of this old Stack Overflow Answer.
Try this.
public bool SendEmail(MailAddress toAddress, string subject, string body)
{
MailAddress fromAddress = new MailAddress("pull from db or web.config", "pull from db or web.config");
string fromPassword = "pull from db or config and decrypt";
string smtpHost = "pull from db or web.config";
int smtpPort = 587;//gmail port
try
{
var smtp = new SmtpClient
{
Host = smtpHost,
Port = smtpPort,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
IsBodyHtml = true
})
{
smtp.Send(message);
}
return true;
}
catch (Exception err)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(err);
return false;
}
}
This is a snippet from one of my projects. It's a little more feature-packed than some of the other implementations.
Using this function allows you to create an email with:
Tokens that can be replaced with actual values at runtime
Emails that contain both a text and HTML view
public MailMessage createMailMessage(string toAddress, string fromAddress, string subject, string template)
{
// Validate arguments here...
// If your template contains any of the following {tokens}
// they will be replaced with the values you set here.
var replacementDictionary = new ListDictionary
{
// Replace with your own list of values
{ "{first}", "Pull from db or config" },
{ "{last}", "Pull from db or config" }
};
// Create a text view and HTML view (both will be in the same email)
// This snippet assumes you are using ASP.NET (works w/MVC)
// if not, replace HostingEnvironment.MapPath with your own path.
var mailDefinition = new MailDefinition { BodyFileName = HostingEnvironment.MapPath(template + ".txt"), IsBodyHtml = false };
var htmlMailDefinition = new MailDefinition { BodyFileName = HostingEnvironment.MapPath(template + ".htm"), IsBodyHtml = true };
MailMessage htmlMessage = htmlMailDefinition.CreateMailMessage(email, replacementDictionary, new Control());
MailMessage textMessage = mailDefinition.CreateMailMessage(email, replacementDictionary, new Control());
AlternateView plainView = AlternateView.CreateAlternateViewFromString(textMessage.Body, null, "text/plain");
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlMessage.Body, null, "text/html");
var message = new MailMessage { From = new MailAddress(from) };
message.To.Add(new MailAddress(toAddress));
message.Subject = subject;
message.AlternateViews.Add(plainView);
message.AlternateViews.Add(htmlView);
return message;
}
Assuming you have your Web.config set up for NetMail, you can call this method from a helper method like so:
public bool SendEmail(MailMessage email)
{
var client = new SmtpClient();
try
{
client.Send(message);
}
catch (Exception e)
{
return false;
}
return true;
}
SendMail(createMailMessage("to#email.com", "from#email.com", "Subject", "~/Path/Template"));