web-dev-qa-db-fra.com

Comment enregistrer un objet MailMessage sur le disque en tant que fichier * .eml ou * .msg

Comment enregistrer un objet MailMessage sur le disque? L'objet MailMessage n'expose aucune méthode Save (). 

Je n'ai pas de problème s'il enregistre dans n'importe quel format, * .eml ou * .msg. Une idée comment faire ça?

77
ashwnacharya

Pour plus de simplicité, je citerai simplement une explication à partir d’un élément Connect :

Vous pouvez réellement configurer le SmtpClient pour envoyer des emails au fichier système au lieu du réseau. Vous pouvez faites cela par programme en utilisant le code suivant:

SmtpClient client = new SmtpClient("mysmtphost");
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = @"C:\somedirectory";
client.Send(message);

Vous pouvez également configurer cela dans votre fichier de configuration d'application tel que ce:

 <configuration>
     <system.net>
         <mailSettings>
             <smtp deliveryMethod="SpecifiedPickupDirectory">
                 <specifiedPickupDirectory pickupDirectoryLocation="C:\somedirectory" />
             </smtp>
         </mailSettings>
     </system.net>
 </configuration>

Après avoir envoyé l'e-mail, vous devriez voir les fichiers de messagerie sont ajoutés à la répertoire que vous avez spécifié. Vous pouvez alors avoir un processus séparé envoyer le messages électroniques en mode batch.

Vous devriez pouvoir utiliser le constructeur vide au lieu de celui répertorié, car il ne l'enverra de toute façon pas.

113
Ryan Versaw

Voici une méthode d'extension permettant de convertir un MailMessage en un flux contenant les données EML . C'est évidemment un peu un bidouillage, car il utilise le système de fichiers, mais cela fonctionne.

public static void SaveMailMessage(this MailMessage msg, string filePath)
{
    using (var fs = new FileStream(filePath, FileMode.Create))
    {
        msg.ToEMLStream(fs);
    }
}

/// <summary>
/// Converts a MailMessage to an EML file stream.
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public static void ToEMLStream(this MailMessage msg, Stream str)
{
    using (var client = new SmtpClient())
    {
        var id = Guid.NewGuid();

        var tempFolder = Path.Combine(Path.GetTempPath(), Assembly.GetExecutingAssembly().GetName().Name);

        tempFolder = Path.Combine(tempFolder, "MailMessageToEMLTemp");

        // create a temp folder to hold just this .eml file so that we can find it easily.
        tempFolder = Path.Combine(tempFolder, id.ToString());

        if (!Directory.Exists(tempFolder))
        {
            Directory.CreateDirectory(tempFolder);
        }

        client.UseDefaultCredentials = true;
        client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
        client.PickupDirectoryLocation = tempFolder;
        client.Send(msg);

        // tempFolder should contain 1 eml file

        var filePath = Directory.GetFiles(tempFolder).Single();

        // stream out the contents
        using (var fs = new FileStream(filePath, FileMode.Open))
        {
            fs.CopyTo(str);
        }

        if (Directory.Exists(tempFolder))
        {
            Directory.Delete(tempFolder, true);
        }
    }
}

Vous pouvez ensuite prendre le flux renvoyé et le faire à votre guise, y compris l’enregistrement dans un autre emplacement sur le disque, le stockage dans un champ de base de données, ou même l’envoi d’un e-mail en pièce jointe.

24
saille

Si vous utilisez Mailkit . Il suffit d'écrire ci-dessous le code 

string fileName = "your filename full path";
MimeKit.MimeMessage message = CreateMyMessage ();
message.WriteTo (fileName);
2
Naveen Soni

Pour une raison ou une autre, le client.send a échoué (juste après un envoi effectif en utilisant cette méthode), alors j'ai branché un bon flux CDO et ADODB. J'ai également dû charger CDO.message avec un fichier template.eml avant de définir les valeurs .Message. Mais ça marche.

Puisque celui ci-dessus est C, en voici un pour VB

    MyMessage.From = New Net.Mail.MailAddress(mEmailAddress)
    MyMessage.To.Add(mToAddress)
    MyMessage.Subject = mSubject
    MyMessage.Body = mBody

    Smtp.Host = "------"
    Smtp.Port = "2525"
    Smtp.Credentials = New NetworkCredential(------)

    Smtp.Send(MyMessage)        ' Actual Send

    Dim oldCDO As CDO.Message
    oldCDO = MyLoadEmlFromFile("template.eml")  ' just put from, to, subject blank. leave first line blank
    oldCDO.To = mToAddress
    oldCDO.From = mEmailAddress
    oldCDO.Subject = mSubject
    oldCDO.TextBody = mBody
    oldCDO.HTMLBody = mBody
    oldCDO.GetStream.Flush()
    oldCDO.GetStream.SaveToFile(yourPath)
0
Gregory Way