So speichern Sie das MailMessage-Objekt auf der Festplatte als * .eml- oder * .msg-Datei

86

Wie speichere ich ein MailMessage-Objekt auf der Festplatte? Das MailMessage-Objekt macht keine Save () -Methoden verfügbar.

Ich habe kein Problem, wenn es in irgendeinem Format speichert, * .eml oder * .msg. Irgendeine Idee, wie das geht?

Ashwnacharya
quelle

Antworten:

122

Der Einfachheit halber zitiere ich nur eine Erklärung aus einem Connect-Element :

Sie können den SmtpClient tatsächlich so konfigurieren, dass E-Mails anstelle des Netzwerks an das Dateisystem gesendet werden. Sie können dies programmgesteuert mit dem folgenden Code tun:

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

Sie können dies auch in Ihrer Anwendungskonfigurationsdatei wie folgt einrichten:

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

Nach dem Senden der E-Mail sollte angezeigt werden, dass E-Mail-Dateien zu dem von Ihnen angegebenen Verzeichnis hinzugefügt werden. Sie können dann die E-Mail-Nachrichten im Batch-Modus von einem separaten Prozess senden lassen.

Sie sollten in der Lage sein, den leeren Konstruktor anstelle des aufgelisteten zu verwenden, da er ohnehin nicht gesendet wird.

Ryan Versaw
quelle
1
Ich habe festgestellt, dass ich zusätzlich zu den von Ryan bereitgestellten Informationen auch den <network host = "..." usw. hinzufügen musste.
Steven Rogers
10
Gibt es eine Möglichkeit, den Dateinamen der Ausgabe-EML-Datei zu ändern? Ich würde es vorziehen, nicht wie folgt auszusehen: f80f4695-551c-47d7-8879-40ad89707b23.eml Danke!
Buzzzzjay
8
Obwohl es sich um einen alten Beitrag handelt, möchte ich eine Antwort auf die letzte Frage von @buzzzzjay hinzufügen: Schauen Sie hier: Link
Corné Hogerheijde
Danke für den Link, das ist wirklich hilfreich!
Buzzzzjay
gut, es funktioniert bei mir. Wie kann ich Outlook öffnen, um gerade gespeicherte Dateien auf der Clientseite zu öffnen?
Builder
28

Hier ist eine Erweiterungsmethode zum Konvertieren einer MailMessage in einen Stream mit den EML-Daten. Es ist offensichtlich ein kleiner Hack, da es das Dateisystem verwendet, aber es funktioniert.

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);
        }
    }
}

Sie können dann den zurückgegebenen Stream nehmen und damit tun, was Sie möchten, einschließlich Speichern an einem anderen Speicherort auf der Festplatte oder Speichern in einem Datenbankfeld oder sogar E-Mail als Anhang.

Saille
quelle
1
Hallo Saille ... Ihr Code funktioniert gut und ja, er erstellt die eml- oder Msg-Datei, aber ich kann das in MS Outlook nicht öffnen :( Benötigen Sie Ihre Hilfe dabei.
Rahul Jain
2
Die EML-Datei sollte in Outlook geöffnet werden. Wenn dies nicht möglich ist, versuchen Sie, die Dateierweiterung in .MHT umzubenennen, und öffnen Sie sie dann in Internet Explorer.
Saille
Saille - ist es möglich, ohne eine "Von" -Adresse zu speichern, damit sie von dem Benutzer gesendet werden kann, der sie öffnet? Prost.
Andy Jones
Du müsstest es versuchen. Ich kann mir vorstellen, dass Ihr E-Mail-Client die Antwortadresse entsprechend seinen Einstellungen festlegen möchte.
Saille
7

Wenn Sie Mailkit verwenden . Schreiben Sie einfach den folgenden Code

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

Aus dem einen oder anderen Grund ist client.send fehlgeschlagen (direkt nach einem tatsächlichen Versand mit dieser Methode), sodass ich einen guten alten CDO- und ADODB-Stream angeschlossen habe. Ich musste auch CDO.message mit einer template.eml laden, bevor ich die .Message-Werte festlegte. Aber es funktioniert.

Da das obige C ist, ist hier eins für 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
quelle
Willkommen bei StackOverflow! Da die Frage mit dem Tag c # versehen ist , sind Antworten in anderen Sprachen leider nicht hilfreich.
Hille
0

Versuche dies

Bitte verwenden Sie diese 2 Referenzen (mit MailBee;) (mit 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
quelle