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

87

Comment enregistrer l'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 cela?

ashwnacharya
la source

Réponses:

123

Pour plus de simplicité, je vais simplement citer une explication d'un élément Connect :

Vous pouvez en fait configurer le SmtpClient pour envoyer des e-mails au système de fichiers au lieu du réseau. Vous pouvez le faire par programme à l'aide du code suivant:

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

Vous pouvez également configurer cela dans le fichier de configuration de votre application comme ceci:

 <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 e-mail être ajoutés au répertoire que vous avez spécifié. Vous pouvez ensuite demander à un processus distinct d'envoyer les e-mails en mode batch.

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

Ryan Versaw
la source
1
J'ai trouvé que j'avais également besoin d'ajouter le <network host = "...", etc. en plus de ce que Ryan a fourni.
Steven Rogers
10
Existe-t-il un moyen de modifier le nom de fichier du fichier .eml de sortie? Je préférerais que cela ne ressemble pas à ce qui suit: f80f4695-551c-47d7-8879-40ad89707b23.eml Merci!
buzzzzjay
8
Bien qu'il s'agisse d'un ancien post, je voudrais ajouter une réponse à la dernière question de @buzzzzjay: jetez un œil ici: lien
Corné Hogerheijde
Merci pour le lien, c'est vraiment utile!
buzzzzjay
bon, ça marche pour moi. En outre, comment puis-je ouvrir Outlook pour ouvrir juste le fichier enregistré côté client.
Builder
29

Voici une méthode d'extension pour convertir un MailMessage en un flux contenant les données EML. C'est évidemment un peu un hack 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 en faire ce que vous voulez, y compris l'enregistrement dans un autre emplacement sur le disque ou le stockage dans un champ de base de données, ou même l'envoi par courrier électronique en pièce jointe.

saille
la source
1
Salut Saille ... Votre code fonctionne bien et oui, il crée le fichier eml ou Msg mais je ne peux pas l'ouvrir dans MS Outlook :( Besoin de votre aide pour le faire.
Rahul Jain
2
Le fichier .EML devrait s'ouvrir dans Outlook, mais si vous ne pouvez pas, essayez de renommer l'extension de fichier en .MHT, puis ouvrez-le dans Internet Explorer.
saille
Saille - est-il possible d'enregistrer sans adresse «de», afin qu'il puisse être envoyé par l'utilisateur qui l'ouvre? À votre santé.
Andy Jones
Il faudrait l'essayer. J'imagine que votre client de messagerie voudrait définir l'adresse de réponse en fonction de ses paramètres.
saille
7

Si vous utilisez Mailkit . Écrivez juste ci-dessous le code

string fileName = "your filename full path";
MimeKit.MimeMessage message = CreateMyMessage ();
message.WriteTo(fileName);
Naveen
la source
0

Pour une raison ou une autre, client.send a échoué (juste après un envoi réel en utilisant cette méthode), j'ai donc branché le bon vieux flux CDO et ADODB. J'ai également dû charger CDO.message avec un 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)
Gregory Way
la source
Bienvenue dans StackOverflow! Comme la question est avec la balise c # , les réponses dans d'autres langues ne sont pas utiles, désolé.
Hille
0

essaye ça

veuillez utiliser ces 2 références (en utilisant MailBee;) (en utilisant MailBee.Mime;)

    public static string load(string to,string from,string cc,string bcc,string subject,string body, List<string> reportList,string path, bool HtmlbodyType)
    {
        try
        {
            MailBee.Mime.MailMessage msg = new MailBee.Mime.MailMessage();
            msg.From.AsString = from;
            msg.Subject = subject;
            if (HtmlbodyType == true)
            {
                msg.BodyHtmlText = body;
            }
            else
            {
                msg.BodyPlainText = body;
            }
            
            string[] receptionEmail = to.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
            string[] ccEmail = cc.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
            string[] bccEmail = bcc.Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
            string message = "";
            foreach (string To in receptionEmail)
            {
                msg.To.Add(To);
            }
            foreach (string CC in ccEmail)
            {
                    msg.Cc.Add(CC);
            }
            foreach (string Bcc in bccEmail)
            {
                    msg.Bcc.Add(Bcc);

            }
                for (int x = 0; x < reportList.Count; x++)
                {
                    string fileName = reportList[x];
                    msg.Attachments.Add(fileName);
                }

                msg.SaveMessage(path);
                return "Success";
            
        }
        catch (Exception ex)
        {
            return ex.Message;
        }

    }
Mohamed Husama
la source