4

I have an interface for sending mails

public interface IMailSender
{
    void SendMail(MailMessage message);
}

When I create a mail I use AlternateView for that (plain text and html)

And now I would like to create a SendGridMailSender class that implements that interface, but my problem is that I don't know how to I populate the SendGrid.Html and SendGrid.Text based on the MailMessage. The only solution I could find means using a StreamReader and accesing the AlternateViewsCollection by index, I would like to thing there's a better solution that I can't figure out.

public void SendMail(MailMessage message)
{
        var sendGridMessage = CreateSendGridMessage(message);

        // Create network credentials to access your SendGrid account.
        var user = "userCredential";
        var pswd = "userPaswd";

        var credentials = new NetworkCredential(user, pswd);

        // Create an SMTP transport for sending email.
        var transportSMTP = SMTP.GetInstance(credentials);

        // Send the email.
        transportSMTP.Deliver(sendGridMessage);
}

private SendGrid CreateSendGridMessage(MailMessage mail)
{
    var sendGridMessage = SendGrid.GetInstance();

    sendGridMessage.From = mail.From;

    var recipients = mail.To;

    foreach (var recipient in recipients)
    {
        sendGridMessage.AddTo(recipient.ToString());
    }

    var stream = mail.AlternateViews[0].ContentStream;
    using (var reader = new StreamReader(stream))
    {
        sendGridMessage.Text = reader.ReadToEnd();
    }

    stream = mail.AlternateViews[1].ContentStream;
    using (var reader = new StreamReader(stream))
    {
        sendGridMessage.Html = reader.ReadToEnd();
    }

    return sendGridMessage;
}

Thanks

mitomed
  • 2,006
  • 2
  • 29
  • 58
  • I noticed you asked this question earlier because I left a comment on the previous version before you deleted it, it's better to update the original question than to repost FYI. – Swift May 20 '13 at 21:32
  • Yes, Swift. I was about to update it in order to clarify the question but to be honest it was so messy that even myself found difficult to understood it after a few hours. Anyway you are probably right and even though I should have edited it, my fault – mitomed May 20 '13 at 21:41

2 Answers2

4

The only way to access the AlternateView content is through the stream, so your solution is correct, although you should also check the ContentType to ensure that mail.AlternateViews[0] is in fact your Text part and so on.

bwest
  • 9,182
  • 3
  • 28
  • 58
1

Have you thought about using the official C# library instead? It makes it super simple to do what you're trying to do

// Create the email object first, then add the properties.
var myMessage = SendGrid.GetInstance();

// Add the message properties.
myMessage.From = new MailAddress("john@example.com");

// Add multiple addresses to the To field.
List<String> recipients = new List<String>
{
    @"Jeff Smith <jeff@example.com>",
    @"Anna Lidman <anna@example.com>",
    @"Peter Saddow <peter@example.com>"
};

myMessage.AddTo(recipients);

myMessage.Subject = "Testing the SendGrid Library";

//Add the HTML and Text bodies
myMessage.Html = "<p>Hello World!</p>";
myMessage.Text = "Hello World plain text!";

https://github.com/sendgrid/sendgrid-csharp

Swift
  • 13,118
  • 5
  • 56
  • 80
  • Thanks Swift. Yes that was my original code but what I'm trying to achieve now is to implement the interface and for that I need to receive a MailMessage as a parameter. The rest of the SendGrid instance/message seems quite straightforward to populate but these Html and Text bodies don't, as I only could do it with that streamreader – mitomed May 20 '13 at 21:46