1

I am trying to find a reliable way to be able to send emails using the system default external mail client from my WPF app.

I know similar questions are already posted on stackoverflow (Open default mail client along with a attachment), but they are outdated and I couldn't find any solution which is robust enough.

My requirements:

  • Works from a WPF desktop app on W10
  • Use the external email client which is the user's default app for Email
  • Works with the most popular email apps (Outlook, Thunderbird, the Mail app in Windows)
  • Attachments
  • HTML, plain text and RTF body
  • The email appears in the drafts folder and recognized as a new, unsent message by the clients

The things I've found so far:

  • mailto links: no-go because no attachment support
  • EML file: issues like the from field has to be explicitly set and also the message is not marked as a new unsent message by some clients even if the "X-Unsent: 1" is set
  • MAPI: Depricated by MS and they themselves do not recommend using it. People complaining about several bugs and issues. Also the default mail client is not recognized properly on Windows 10.

So far MAPI seems to be the best option but honestly I don't like any of them but I couldn't find any better alternative.

hthms
  • 853
  • 1
  • 10
  • 25
  • Did you looked at SmtpClient? Check this out:https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.send?view=netframework-4.8 – Julian Mar 25 '20 at 11:32
  • You can send email using [`Gmail SMTP`](https://stackoverflow.com/questions/60814553/access-denied-when-sending-a-mail-from-c-sharp-programm/60828753#60828753) which is easy and developer friendly – Md Farid Uddin Kiron Mar 25 '20 at 11:32
  • @Julian SmtpClient is not good, we need to support external mail clients as well. – hthms Mar 25 '20 at 11:39

1 Answers1

0

You can simply use Mailkit

  • It works from any app, which is using .NET.
  • It supports HTML, plain text and also RTF body
  • Yes, the email appears in the drafts folder and recognized as a new, you can achieve it.
  • It supports attachments

Usage is quite simple, I can give you an example of how I am using it in my hobby project.

I am not using attachments, but with Mailkit, it is very easy to do that. You can check their FAQ

But anyway I will post here how I am using it.

1) First create message class, which will be responsible to handle Subject, content and mail info about the person you are sending the email. With the simple constructor, you will seed put into your properties.

using System;
using MimeKit;

namespace SomeNamespace
{
    public class Message
    {
        public List<MailboxAddress> To { get; set; }
        public string Subject { get; set; }
        public string Content { get; set; }

        public Message(IEnumerable<string> to, string subject, string content)
        {
            To = new List<MailboxAddress>();

            To.AddRange(to.Select(x => new MailboxAddress(x)));
            Subject = subject;
            Content = content;
        }
    }
}

2) You will need also your SMTP configuration class, which will have information about your email. (From where you will send mails)

using System;
namespace SomeNamespace
{
    public class EmailConfiguration
    {
        public string SMTPFrom { get; set; }
        public string SMTPHost { get; set; }
        public int SMTPPort { get; set; }
        public string SMTPLogin { get; set; }
        public string SMTPPassword { get; set; }
    }
}

3) Then you will create your simple Interface

  public interface IEmailSender
    {
        void SendEmail(Message message);
    }

4) Then you will create an implementation of your service.

using System;
using MailKit.Net.Smtp;
using MimeKit;
using SomeNamespace.Configuration;
using SomeNamespace.Services.Interfaces;

namespace SomeNamespace
{
    public class EmailSender : IEmailSender
    {
        private readonly EmailConfiguration _emailConfig;

        public EmailSender(EmailConfiguration emailConfig)
        {
            _emailConfig = emailConfig;
        }

        public void SendEmail(Message message)
        {
            var emailMessage = CreateEmailMessage(message);

            Send(emailMessage);
        }

        private MimeMessage CreateEmailMessage(Message message)
        {
            var emailMessage = new MimeMessage();
            emailMessage.From.Add(new MailboxAddress(_emailConfig.SMTPFrom));
            emailMessage.To.AddRange(message.To);
            emailMessage.Subject = message.Subject;
            emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Text) { Text = message.Content };

            return emailMessage;
        }

        private void Send(MimeMessage mailMessage)
        {
            using (var client = new SmtpClient())
            {
                try
                {
                    client.Connect(_emailConfig.SMTPHost, _emailConfig.SMTPPort, true);
                    client.AuthenticationMechanisms.Remove("XOAUTH2");
                    client.Authenticate(_emailConfig.SMTPLogin, _emailConfig.SMTPPassword);

                    client.Send(mailMessage);
                }
                catch(Exception message)
                {
                    Console.WriteLine(message);
                    throw;
                }
                finally
                {
                    client.Disconnect(true);
                    client.Dispose();
                }
            }
        }
    }
}

The last step is to create your Message and EmailConfiguration models. Create the instance of the EmailSender and send the email.

var message = new Message("whotosend@gmail.com", "Some example Subject", "Some example content");

var emailConfiguration = new EmailConfiguration()
{
    SMTPFrom = "yourSmtpAdress",
    SMTPHost = "yourSmtpHost",
    SMTPLogin = "yourSmtpLogin",
    SMTPPassword = "yourSmtpPassword",
    SMTPPort = 465
};

var _emailSender = new EmailSender(emailConfiguration);

_emailSender.SendEmail(message);

Of course, you can use DI to create your service instances but it's up to you.

Stay home, stay safe, wish you happy coding.

Tornike Gomareli
  • 1,564
  • 2
  • 16
  • 28
  • 1
    Hi, thanks for the detailed answer but I need my email to be sent by the external mail app set as default on the user's computer. We already have a solution for a built-in email client but we also have to support as many 3rdparty email apps as possible. – hthms Mar 25 '20 at 12:08