diff --git a/.travis.yml b/.travis.yml
index 8f8874dd6..da9ab1b6c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
language: csharp
-dotnet: 1.0.4
+dotnet: 2.1
os: linux
dist: trusty
mono: latest
@@ -24,9 +24,10 @@ before_script:
script:
- dotnet restore
- dotnet build ./src/SendGrid -c Release
- - dotnet test ./tests/SendGrid.Tests/SendGrid.Tests.csproj -c Release -f netcoreapp1.0
+ - dotnet test ./tests/SendGrid.Tests/SendGrid.Tests.csproj -c Release -f netcoreapp2.0
- ls ./src/SendGrid/bin/Release/net452/
- ls ./src/SendGrid/bin/Release/netstandard1.3/
+ - ls ./src/SendGrid/bin/Release/netstandard2.0/
- dotnet pack ./src/SendGrid -c Release
- curl -s https://codecov.io/bash > .codecov
- chmod +x .codecov
diff --git a/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs b/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs
new file mode 100644
index 000000000..265927d9f
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/MailMessageExtensions.cs
@@ -0,0 +1,137 @@
+//
+// Copyright (c) SendGrid. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+#if NETSTANDARD2_0 || NET452
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Mail;
+
+namespace SendGrid.Helpers.Mail
+{
+ ///
+ /// A collection of extension to assist with the conversion of System.Net.Mail.MailMessage to
+ ///
+ public static class MailMessageExtensions
+ {
+ ///
+ /// Converts a System.Net.Mail.MailAddress to a sendgrid address
+ ///
+ /// The address to be converted
+ /// The result of the conversion
+ public static EmailAddress ToSendGridAddress(this MailAddress address)
+ {
+ return string.IsNullOrWhiteSpace(address.DisplayName) ?
+ new EmailAddress(address.Address) :
+ new EmailAddress(address.Address, address.DisplayName.Replace(",", string.Empty).Replace(";", string.Empty));
+ }
+
+ ///
+ /// Copies the attachment from a MailMessage into the object as a base64 string.
+ ///
+ /// The attachment to be converted
+ /// Returns a
+ public static SendGrid.Helpers.Mail.Attachment ToSendGridAttachment(this System.Net.Mail.Attachment attachment)
+ {
+ using (var stream = new MemoryStream())
+ {
+ attachment.ContentStream.CopyTo(stream);
+ return new SendGrid.Helpers.Mail.Attachment()
+ {
+ Disposition = "attachment",
+ Type = attachment.ContentType.MediaType,
+ Filename = attachment.Name,
+ ContentId = attachment.ContentId,
+ Content = Convert.ToBase64String(stream.ToArray())
+ };
+ }
+ }
+
+ ///
+ /// Converts a System.Net.Mail.MailMessage to a SendGrid message.
+ ///
+ /// The MailMessage to be converted
+ /// Returns a with the properties from the MailMessage
+ public static SendGridMessage ToSendGridMessage(this MailMessage message)
+ {
+ var sendgridMessage = new SendGridMessage();
+
+ sendgridMessage.From = ToSendGridAddress(message.From);
+
+ if (message.ReplyToList.Any())
+ {
+ if (message.ReplyToList.Count > 1)
+ {
+ throw new ArgumentException("Sendgrid only supports one reply to address.");
+ }
+
+ sendgridMessage.ReplyTo = message.ReplyToList.Single().ToSendGridAddress();
+ }
+
+ if (message.To.Any())
+ {
+ var tos = message.To.Select(ToSendGridAddress).ToList();
+ sendgridMessage.AddTos(tos);
+ }
+
+ if (message.CC.Any())
+ {
+ var cc = message.CC.Select(ToSendGridAddress).ToList();
+ sendgridMessage.AddCcs(cc);
+ }
+
+ if (message.Bcc.Any())
+ {
+ var bcc = message.Bcc.Select(ToSendGridAddress).ToList();
+ sendgridMessage.AddBccs(bcc);
+ }
+
+ if (!string.IsNullOrWhiteSpace(message.Subject))
+ {
+ sendgridMessage.Subject = message.Subject;
+ }
+
+ if (message.Headers.Count > 0)
+ {
+ var headers = message.Headers.AllKeys.ToDictionary(x => x, x => message.Headers[x]);
+ sendgridMessage.AddHeaders(headers);
+ }
+
+ if (!string.IsNullOrWhiteSpace(message.Body))
+ {
+ var content = message.Body;
+
+ if (message.IsBodyHtml)
+ {
+
+ if (content.StartsWith("
{message.Body}";
+ }
+
+ sendgridMessage.AddContent("text/html", content);
+ }
+ else
+ {
+ sendgridMessage.AddContent("text/plain", content);
+ }
+ }
+
+ if (message.Attachments.Any())
+ {
+ sendgridMessage.Attachments = new List();
+ sendgridMessage.Attachments.AddRange(message.Attachments.Select(ToSendGridAttachment));
+ }
+
+ return sendgridMessage;
+ }
+ }
+}
+#endif
diff --git a/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs b/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs
new file mode 100644
index 000000000..fc1117648
--- /dev/null
+++ b/tests/SendGrid.Tests/Helpers/Mail/MailMessageExtensionsTests.cs
@@ -0,0 +1,105 @@
+using System.IO;
+using System.Linq;
+using System.Net.Mail;
+using SendGrid.Helpers.Mail;
+using Xunit;
+
+namespace SendGrid.Tests.Helpers.Mail
+{
+ public class MailMessageExtensionsTests
+ {
+ [Theory]
+ [InlineData("Example@example.com")]
+ [InlineData("Example+data@example.com")]
+ public void ConvertEmailAddresses(string email)
+ {
+ var address = new MailAddress(email).ToSendGridAddress();
+ Assert.Equal(email, address.Email);
+ }
+
+ [Theory]
+ [InlineData("Example@example.com", "Ben@example.com", "Widget Factory Production", "Ben, widget production is down 15%, could you investigate?")]
+ public void TestSimpleMailMessageEmail(string from, string to, string subject, string body)
+ {
+ var mail = new MailMessage(from, to)
+ {
+ Subject = subject,
+
+ };
+
+ mail.Body = body;
+
+ var message = mail.ToSendGridMessage();
+
+ Assert.Equal(from, message.From.Email);
+ Assert.Equal(subject, message.Subject);
+ Assert.Contains(message.Personalizations.SelectMany(x => x.Tos), x => x.Email == to);
+ Assert.Contains(message.Contents, x => x.Value == body);
+ }
+
+ [Theory]
+ [InlineData("Example@example.com", "Ben@example.com", "Widget Factory Production", "Management@example.com", "HR@example.com")]
+ public void TestMailMessageEmailWithCC(string from, string to, string subject, string cc, string bcc)
+ {
+ var mail = new MailMessage(from, to)
+ {
+ Subject = subject
+ };
+
+ mail.CC.Add(cc);
+ mail.Bcc.Add(bcc);
+
+ var message = mail.ToSendGridMessage();
+
+
+ Assert.Equal(from, message.From.Email);
+ Assert.Equal(subject, message.Subject);
+ Assert.Contains(message.Personalizations.SelectMany(x => x.Tos), x => x.Email == to);
+ Assert.Contains(message.Personalizations.SelectMany(x => x.Ccs), x => x.Email == cc);
+ Assert.Contains(message.Personalizations.SelectMany(x => x.Bccs), x => x.Email == bcc);
+ }
+
+ [Theory]
+ [InlineData("Example@example.com", "Ben@example.com", "invoicing@example.com")]
+ public void TestSimpleMailMessageReplyTo(string from, string to, string replyTo)
+ {
+ var mail = new MailMessage(from, to);
+ mail.ReplyToList.Add(replyTo);
+
+ var message = mail.ToSendGridMessage();
+
+ Assert.Equal(replyTo, message.ReplyTo.Email);
+ }
+
+ [Fact]
+ public void TestMailMessageShouldConvertAttachements()
+ {
+ var mail = new MailMessage("Ben@Example.com", "HR@Example.com");
+ var data = new byte[] { 0x1, 0x2, 0x3, 0x4 };
+
+ SendGridMessage message = null;
+
+ using (var stream = new MemoryStream(data))
+ {
+ mail.Attachments.Add(new System.Net.Mail.Attachment(stream, "Example.pdf"));
+ message = mail.ToSendGridMessage();
+ }
+
+ Assert.NotEmpty(message.Attachments);
+ var attachment = message.Attachments.Single();
+ Assert.Equal("Example.pdf", attachment.Filename);
+ Assert.False(string.IsNullOrEmpty(attachment.Content));
+ }
+
+ [Fact]
+ public void TestMailMessageHeaderConverted()
+ {
+ var mail = new MailMessage("Ben@Example.com", "HR@Example.com");
+ mail.Headers.Add("Example", "Example");
+
+ var message = mail.ToSendGridMessage();
+ var headers = message.Personalizations.SelectMany(x => x.Headers);
+ Assert.Contains(headers, x => x.Key == "Example" && x.Value == "Example");
+ }
+ }
+}
diff --git a/tests/SendGrid.Tests/SendGrid.Tests.csproj b/tests/SendGrid.Tests/SendGrid.Tests.csproj
index b76f91437..a810e8027 100644
--- a/tests/SendGrid.Tests/SendGrid.Tests.csproj
+++ b/tests/SendGrid.Tests/SendGrid.Tests.csproj
@@ -1,11 +1,11 @@
- netcoreapp1.0
+ netcoreapp2.0
SendGrid.Tests
SendGrid.Tests
true
- 1.0.4
+ 2.0.9
false
false
false