简体   繁体   中英

Send eml files saved on disk

I am creating eml's and saving them to a directory using procedure mentioned over here . I want to know how to send these eml files? I tried using SMTPClient class's object but it takes MailMessage object as its parameter and I couldn't find and way to create an object of type MailMessage using these saved eml files.

Loading an EML file correctly is not as easy as it looks. You can write an implementation working in 95% cases within few days. Remaining 5% would take at least several months ;-). I know, becase I involved in developing one.

Consider following dificulities:

  • unicode emails
  • right-to-left languages
  • correcting malformed EML files caused by well known errors in popular mail clients and servers
  • dealing with S/MIME (encrypted and signed email messages)
  • dealing correctly with several methods of encoding attachments
  • dealing with inline images and stylesheets embedded into HTML emails
  • making sure that it parses correctly a MIME torture message from Mike Crispin (coauthor of Mime and IMAP RFCs)
  • making sure that malformed message will not result in buffer overun or other application crash
  • handling hierarchical messages (message with attached messages)
  • making sure that it handles correctly very big emails

Maturing of such parser takes years and continuous feedback for it's users. Right now is no such parser included in the .NET Framework. Until it changes I would sugest getting a thrid party MIME parser from an established vendor.

Following code uses our Rebex Secure Mail component , but I'm sure that similar task could be replicated easily with components from other vendors as well.

The code is based on Mail Message tutorial .

// create an instance of MailMessage 
MailMessage message = new MailMessage();

// load the message from a local disk file 
message.Load("c:\\message.eml");

// send message
Smtp.Send(message, "smtp.example.org");

Use EMLReader to retrieve data from .eml file. It contains all the data you need to create a MailMessage object like From, To, Subject, Body & a whole lot more.

FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite);
EMLReader reader = new EMLReader(fs);
fs.Close();

MailMessage message = new System.Net.Mail.MailMessage(reader.From, reader.To, reader.Subject, reader.Body);

If you're a Microsoft shop and have an Exchange server anyway, then there's another solution which is much, much easier than everything else suggested here:

Each Exchange server has a pickup directory configured out of the box.
By default, it's %ExchangeInstallPath%TransportRoles\\Pickup .

You just copy the .eml files to that directory, and Exchange automatically will send the mails.


Read this TechNet article for more information:
Pickup directory and Replay directory

Do What i did ... give up.

Building the MailMessage object seems to be the focus i have a similar questions outstanding on here too ... How do i send an email when i already have it as a string?

From what i've seen the simplest way to do this is to use a raw socket to dump the entire .eml file contents up to the mail server as is and let the mail server figure out the hard stuff like from, to subject, ect by parsing the email using it's engine.

The only problem ... RFC 821 ... such a pain, i'm trying to figure out a clean way to do this and read mail already in the mailbox quickly too.

EDIT:

I found a clean solution and covered it in my thread :)

How do i send an email when i already have it as a string?

For the records:

In Nuget Packager Console write:

Install-Package LumiSoft.Net.dll

Then in your Code:

using (FileStream fs = new FileStream( cacheFileName, FileMode.Open, FileAccess.Read )) 
using (LumiSoft.Net.SMTP.Client.SMTP_Client client = 
   new LumiSoft.Net.SMTP.Client.SMTP_Client())
{
    client.SendMessage( fs );
}

As others demonstrated, EML is just not a good way to serialize a mail message. You might be better off by saving your mails in another format. While there are several serialization engines in the .Net framework to serialize any object, you might also consider just saving the components of your mails, like addresses, body, files to be attached in base64, in an Xml file of your own design.

Below is an example to get you started:

    <?xml version="1.0" encoding="utf-8"?>
    <mail>
      <to display="Thomas Edison" address="tedison@domain.com" />
      <body>
        Hi Thomas,
        How are you doing?
        Bye
      </body>
      <attachment name="MaryLamb.wav">
        cmF0aWUgYWFuIGluIFBERi1mb3JtYWF0LiBEZSBmYWN0dXVyIGlzIGVlbiBvZmZpY2ll
        ZWwgZ2VzaWduZWVyZA0KZG9jdW1lbnQgdmFuIEV1cm9maW5zIE9tZWdhbSBCVi4gRGUg
        c2lnbmF0dXJlIGt1bnQgdSB2ZXJpZmnDq3Jlbi4NCg0KVm9vciBoZXQgdmVyaWZpw6ty
        ...
      </attachment>
    </mail>

Added advantage would be that, unlike with creating EML, you do not need the smtpClient to build the concept mail files.

Xml is extremely easy to create and parse in C#.

You did not tell the rationale of saving EML's. If long term archival would be a goal, xml might have an advantage.

You can do this with Windows Server's built-in SMTP server, the same way as in the previous answer using Exchange.

Drop the .eml file to C:\\inetpub\\mailroot\\Pickup and the raw message will be sent (local or remote).

You can forward messages by simply inserting a line in the top:

To: email@address.com

You can manipulate the mail header further if you require.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM