1

I'm trying to convert some Python code for use in a .Net website. The code retrieves a message stored in RFC822 format and sends the message to an SMTP server again using:

mail from: blah blah
rcpt to: blah blah
data
<send the text from the RFC822 file here>
.

So no parsing of the RFC822 file is required (fortunately!). In Python this is simply:

smtp = smtplib.SMTP(_SMTPSERVER)
smtp.sendmail(_FROMADDR, recipient, msg)

where the file has been read into the variable msg. Is there an easy way to do this in C#?

The built in C# SMTP objects don't offer a way to do this, or at least I haven't found a way. They seem to be based on the principle of building up a MailMessage by providing the addresses, subject and body separately. SmtpClient has a Send(string, string, string, string) method, but again this requires a separate subject and body so I guess it constructs the RFC822 formatted message for you.

If necessary I can write my own class to send the mail. It's such a simple requirement that it wouldn't take long. However if there is a way using the standard libraries they're probably less buggy than my code.

user2771704
  • 5,994
  • 6
  • 37
  • 38
John Rennie
  • 254
  • 2
  • 12

3 Answers3

4

I would recommend using MimeKit to parse the message file and then use MailKit to send via SMTP. MailKit is based on MimeKit, so they work well together and MailKit's SmtpClient is superior to System.Net.Mail's implementation.

Parsing a message is as simple as this:

var message = MimeMessage.Load (fileName);

Sending the message is as simple as these few lines:

using (var client = new SmtpClient ()) {
    client.Connect ("smtp.gmail.com", 465, true);
    client.Authenticate ("username", "password");
    client.Send (message);
    client.Disconnect (true);
}
jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Thanks Jeffrey, but there is no need to parse the RFC822 file. It just needs sending, as it is, down a socket to the SMTP server. It took me about an hour to write a simple class using TcpClient to send the file. Polynomial's estimate of 50 lines proved rather optimistic by the time I'd added all the exception tracking, but it was still a quick job. – John Rennie Sep 27 '14 at 05:03
1

You're right, the inbuilt stuff doesn't offer a solution for this.

My advice would be to simply write a bit of code that uses TcpClient and StreamReader / StreamWriter to interact with the SMTP server. It shouldn't need more than 50 lines of code.

Polynomial
  • 27,674
  • 12
  • 80
  • 107
  • You don't want to have to rewrite the configurability of the SmptClient. If OP wants to use authentication, encryption, a different server and so on, you'll need to use code reading the configuration. – CodeCaster Sep 25 '14 at 10:30
  • @CodeCaster Why not? OP's requirements clearly don't fit what SmtpClient is designed for, and he appears to only be supporting a single SMPT server (or a small number of them). A manual solution should do the job fine. The SMTP protocol is trivially simple for this purpose. – Polynomial Sep 25 '14 at 10:32
  • Thanks, I suspected I was going to end up doing it myself. I have a C++ SMTP class that I wrote back in the stone age, and I can pretty quickly redo that in C# so it's no big deal. If there are no suggestions I'll accept this tomorrow. – John Rennie Sep 25 '14 at 15:50
1

This is easy to do, you need only to install MailKit and MimeKit from nuget. Pay attention because if you don't need authentication, setting "useSsl" to false is not enough, it doesn't work. You need to set MailKit.Security.SecureSocketOptions.None

 var message = MimeMessage.Load("pathToEml");
                using (var client = new MailKit.Net.Smtp.SmtpClient())
                {
                    client.Connect("smtp.yourserver.yourdomain", 25, MailKit.Security.SecureSocketOptions.None);  //set last param to true for authentication
                    //client.Authenticate("username", "password");
                    client.Send(message);
                    client.Disconnect(true);
                }
toma
  • 21
  • 2