This project contains three providers for sending emails. The default is using normal SMTP, in addition we have one for SendGrid, one for Postmark, one for MailGun and one for Amazon SES. All are using the same interface and can easily be switched in and out as required.
We recommend using SendGrid for your application email needs.
See Geta.EmailNotification.Tests for some sample code.
- Support for Razor Views
- Strongly typed access and ViewBag available (see Tests projects, Views/Emails/Test.cshtml)
- Support for BCC, CC, multiple address'
- Fluent API to build email requests with EmailNotificationRequestBuilder
- Support for text and HTML emails
- Support for attachments
- Extension method to easily convert relative to absolute URLs (@Url.Absolute("~/Content/dummy.png")). Use appSettings with key: Geta.EmailNotification.BaseUrl to override the base URL used.
- You can choose to send emails synchronized or async.
Available through Geta's NuGet feed:
- Geta.EmailNotification
- Geta.EmailNotification.Sendgrid
- Geta.EmailNotification.Postmark
- Geta.EmailNotification.Amazon
- Geta.EmailNotification.MailGun
To use SMTP you need to configure it using StructureMap:
For<IEmailViewRenderer>().Use<EmailViewRenderer>();
For<IEmailNotificationClient>().Use<SmtpEmailNotificationClient>();
For<IMailMessageFactory>().Use<MailMessageFactory>();
If you're using Postmark, MailGun or SendGrid then look further down in this documentation for instructions.
public class EmailNotificationRequest
{
public EmailNotificationRequest()
{
this.Attachments = new List<Attachment>();
this.To = new MailAddressCollection();
this.Cc = new MailAddressCollection();
this.Bcc = new MailAddressCollection();
this.ReplyTo = new MailAddressCollection();
this.ViewData = new ViewDataDictionary(this);
}
/// <summary>
/// From email address
/// </summary>
public MailAddress From { get; set; }
/// <summary>
/// To email address'
/// </summary>
public MailAddressCollection To { get; set; }
/// <summary>
/// Copy email address'
/// </summary>
public MailAddressCollection Cc { get; set; }
/// <summary>
/// Blind copy email address'
/// </summary>
public MailAddressCollection Bcc { get; set; }
/// <summary>
/// Reply to email address'
/// </summary>
public MailAddressCollection ReplyTo { get; set; }
public string Subject { get; set; }
/// <summary>
/// HTML content for HTML emails
/// </summary>
public IHtmlString HtmlBody { get; set; }
/// <summary>
/// Text content for fallback or text only emails
/// </summary>
public string Body { get; set; }
/// <summary>
/// Razor view name (without .cshtml)
/// </summary>
public string ViewName { get; set; }
/// <summary>
/// Key/value collection for placeholders
/// </summary>
public ViewDataDictionary ViewData { get; set; }
/// <summary>
/// By default we try and send asynchronous
/// </summary>
public bool SendSynchronous { get; set; }
/// <summary>
/// Attachments for this email message
/// </summary>
public List<Attachment> Attachments { get; set; }
}
public class EmailNotificationResponse
{
/// <summary>
/// True if sent, false otherwise
/// </summary>
public bool IsSent { get; set; }
/// <summary>
/// Any exception or error code/details that the different services return will be added here
/// </summary>
public string Message { get; set; }
}
@using Geta.EmailNotification
@model EmailNotificationRequest
<html>
<body>
<p>Sent: @ViewBag.Date</p>
<p>
Dear @Model.To.First().Address
</p>
<p>
<a href="@Url.Absolute("~/")">This is a link</a>
</p>
<p>
<img src="@Url.Absolute("~/Content/dummy.png")" alt="" />
</p>
</body>
</html>
var client = new SmtpEmailNotificationClient(emailViewRenderer);
var email = new EmailNotificationRequest();
email.To.Add(new MailAddress("frederik@geta.no"));
email.From = new MailAddress("no-reply@example.com");
email.ReplyTo.Add(new MailAddress("reply-to@example.com"));
email.Bcc.Add(new MailAddress("andre@geta.no"));
email.Cc.Add(new MailAddress("maris@geta.no"));
email.Cc.Add(new MailAddress("mattias@geta.no"));
mail.Subject = "Test email";
email.ViewName = "Test";
email.ViewData.Add("Date", DateTime.UtcNow);
client.Send(email);
var client = new SmtpEmailNotificationClient(emailViewRenderer);
var email = new EmailNotificationRequestBuilder()
.WithTo("frederik@geta.no")
.WithFrom("no-reply@example.com")
.WithReplyTo("reply-to@example.com")
.WithBcc("andre@geta.no")
.WithCc("maris@geta.no")
.WithCc("mattias@geta.no")
.WithSubject("Test email")
.WithViewName("Test")
.WithViewData("Date", DateTime.UtcNow)
.Build();
client.Send(email);
var client = new SmtpEmailNotificationClient(emailViewRenderer);
var template = new EmailNotificationRequestBuilder()
.WithSubject("This is template")
.WithFrom("no-reply@example.com")
.WithViewName("Test")
.WithViewData("Date", DateTime.UtcNow)
.Build();
var email1 = new EmailNotificationRequestBuilder(template)
.WithTo("maris@geta.no")
.Build();
var email2 = new EmailNotificationRequestBuilder(template)
.WithTo("mattias@geta.no")
.Build();
client.Send(email1);
client.Send(email2);
It is possible to enable an email whitelist feature. The email whitelist feature makes sure that emails are sent only to emails and domains added into the whitelist. This is useful for test environments where sending emails to all email recipients is prohibited.
First of all, decorate IEmailNotificationClient with WhitelistEmailNotificationClientDecorator. It can be achieved in the StructureMap configuration.
For<IEmailNotificationClient>().DecorateAllWith<WhitelistEmailNotificationClientDecorator>();
For<IEmailNotificationClient>().Use<SmtpEmailNotificationClient>();
Next step, configure a whitelist in the appSettings. Add an item with a key EmailNotification:Whitelist and add whitelist values. Whitelist values can be emails or domains starting with @ sign. Separate those with semicolon (;).
<add key="EmailNotification:Whitelist" value="info@example.com;@geta.no" />
When using the Postmark library you need to configure it using StructureMap.
For<IEmailNotificationClient>().Use<PostmarkEmailNotificationClient>();
For<PostmarkClient>().Use(() => new PostmarkClient(Configuration.Postmark.ApiKey, Configuration.Postmark.ApiBaseUri, Configuration.Postmark.TimeoutInSeconds));
For<IPostmarkMessageFactory>().Use<PostmarkMessageFactory>();
You can get the Postmark API key from https://account.postmarkapp.com. BaseUri is set to: https://api.postmarkapp.com and timeout to 30 seconds by default.
Define and configure using StructureMap
For<IEmailNotificationClient>().Use<MailGunEmailNotificationClient>();
For<IMailgunClient>()
.Use(ctx => new MailgunClient(SiteConfiguration.MailGun.Domain, SiteConfiguration.MailGun.ApiKey, 3));
ApiKey and Domain can be found in MailGun Settings. BaseDomain sets test/live.
To use SendGrid in your project, you need to create a new sendgrid subuser and generate an api key:
- Go to https://sendgrid.com/ and login/create account.
- In settings, go to subuser management and create a new subuser.
- Switch to that subuser account and create an Api Key with the privileges that you deem necessary.
- Store that api key in your favorite secure setting and use it to define and configure through StructureMap:
For<IAsyncEmailNotificationClient>().Use<SendGridEmailNotificationClient>(); // For async calls
For<IEmailNotificationClient>().Use<SendGridEmailNotificationClient>(); // For sync calls
For<ISendGridClient>().Use(ctx => new SendGridClient(<<Your_API_Key>>, "https://api.sendgrid.com", null,"v3", "/mail/send")); //the "/mail/send" url path is one of many endpoints that you can use. Set null for default.
// Dont forget to register your viewengines and mailfactory as defined above:
For<IEmailViewRenderer>().Use<EmailViewRenderer>(() => new EmailViewRenderer(new ViewEngineCollection { new RazorViewEngine() })); // if necessary to create a new view engine
For<IMailMessageFactory>().Use<MailMessageFactory>();
- Check test project and follow the steps used to create sync or async e-mails.
Watch this tutorial to learn how to set up your sender signatures (link branding): Sendgrid - Link branding