Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending Email to SpecifiedPickupDirectory with MailKit

I was using SmtpClient till now with ASP.NET MVC 5. For testing email send functionality on local system, I was using client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;

Now, I want to do the same things in ASP.NET Core which does not have SmtpClient class implemented till now. All search for this ended up on MailKit. I have used their send mail code which is working fine with gmail.

I do not want to send testing emails each time and there may be a lot of scenarios in my project where I need to send email. How can I use the local email sending functionality with MailKit. Any links or little source code will help. Thanks

like image 636
vivek Avatar asked Oct 08 '16 07:10

vivek


People also ask

What is MailKit email?

What is MailKit? MailKit is a cross-platform mail client library. That means you can not only send emails, but you also get everything you need to receive emails. Thanks to MimeKit on that MailKit is built on, you can do everything imaginable with the email itself.


Video Answer


1 Answers

I'm not sure on the finer details of how SmtpDeliveryMethod.SpecifiedPickupDirectory works and what it does exactly, but I suspect it might just save the message in a directory where the local Exchange server periodically checks for mail to send out.

Assuming that's the case, you could do something like this:

public static void SaveToPickupDirectory (MimeMessage message, string pickupDirectory)
{
    do {
        // Generate a random file name to save the message to.
        var path = Path.Combine (pickupDirectory, Guid.NewGuid ().ToString () + ".eml");
        Stream stream;

        try {
            // Attempt to create the new file.
            stream = File.Open (path, FileMode.CreateNew);
        } catch (IOException) {
            // If the file already exists, try again with a new Guid.
            if (File.Exists (path))
                continue;

            // Otherwise, fail immediately since it probably means that there is
            // no graceful way to recover from this error.
            throw;
        }

        try {
            using (stream) {
                // IIS pickup directories expect the message to be "byte-stuffed"
                // which means that lines beginning with "." need to be escaped
                // by adding an extra "." to the beginning of the line.
                //
                // Use an SmtpDataFilter "byte-stuff" the message as it is written
                // to the file stream. This is the same process that an SmtpClient
                // would use when sending the message in a `DATA` command.
                using (var filtered = new FilteredStream (stream)) {
                    filtered.Add (new SmtpDataFilter ());

                    // Make sure to write the message in DOS (<CR><LF>) format.
                    var options = FormatOptions.Default.Clone ();
                    options.NewLineFormat = NewLineFormat.Dos;

                    message.WriteTo (options, filtered);
                    filtered.Flush ();
                    return;
                }
            }
        } catch {
            // An exception here probably means that the disk is full.
            //
            // Delete the file that was created above so that incomplete files are not
            // left behind for IIS to send accidentally.
            File.Delete (path);
            throw;
        }
    } while (true);
}

The above code snippet uses Guid.NewGuid () as a way of generating a temporary filename, but you can use whatever method you want (e.g. you could also opt to use message.MessageId + ".eml").

Based on Microsoft's referencesource, when SpecifiedPickupDirectory is used, they actually also use Guid.NewGuid ().ToString () + ".eml", so that's probably the way to go.

like image 126
jstedfast Avatar answered Oct 11 '22 18:10

jstedfast