Jak zapisać obiekt MailMessage na dysku jako plik * .eml lub * .msg

87

Jak zapisać obiekt MailMessage na dysku? Obiekt MailMessage nie ujawnia żadnych metod Save ().

Nie mam problemu, jeśli zapisuje w jakimkolwiek formacie * .eml lub * .msg. Masz jakiś pomysł, jak to zrobić?

ashwnacharya
źródło

Odpowiedzi:

123

Dla uproszczenia zacytuję tylko wyjaśnienie z pozycji Connect :

W rzeczywistości możesz skonfigurować SmtpClient do wysyłania wiadomości e-mail do systemu plików zamiast do sieci. Możesz to zrobić programowo, używając następującego kodu:

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

Możesz również ustawić to w pliku konfiguracyjnym aplikacji w następujący sposób:

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

Po wysłaniu wiadomości e-mail pliki e-mail powinny zostać dodane do określonego katalogu. Następnie możesz mieć oddzielny proces wysyłania wiadomości e-mail w trybie wsadowym.

Powinieneś być w stanie użyć pustego konstruktora zamiast wymienionego, ponieważ i tak go nie wyśle.

Ryan Versaw
źródło
1
Odkryłem, że oprócz tego, co dostarczył Ryan, muszę również dodać <network host = "..." itp.
Steven Rogers
10
Czy istnieje sposób na zmianę nazwy pliku wyjściowego .eml? Wolałbym, żeby nie wyglądało tak: f80f4695-551c-47d7-8879-40ad89707b23.eml Dzięki!
buzzzzjay
8
Chociaż to stary post, chciałbym dodać odpowiedź na ostatnie pytanie z @buzzzzjay: spójrz tutaj: link
Corné Hogerheijde
Dzięki za link, to jest naprawdę pomocne!
buzzzzjay
dobrze, to działa dla mnie. Dalej, jak mogę otworzyć Outlooka, aby otworzyć właśnie zapisany plik po stronie klienta.
Builder
29

Oto metoda rozszerzenia umożliwiająca konwersję MailMessage na strumień zawierający dane EML. Jest to oczywiście trochę hack, ponieważ używa systemu plików, ale działa.

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

Następnie możesz wziąć zwrócony strumień i robić z nim, co chcesz, w tym zapisywać w innej lokalizacji na dysku lub przechowywać w polu bazy danych, a nawet wysyłać e-mailem jako załącznik.

Saille
źródło
1
Cześć Saille ... Twój kod działa dobrze i tak, tworzy plik eml lub Msg, ale nie mogę tego otworzyć w programie MS Outlook :( Potrzebuję twojej pomocy w zrobieniu tego.
Rahul Jain
2
Plik .EML powinien zostać otwarty w programie Outlook, ale jeśli nie możesz, spróbuj zmienić rozszerzenie pliku na .MHT, a następnie otwórz go w programie Internet Explorer.
saille
Saille - czy można zapisać bez adresu „od”, aby można było go wysłać od użytkownika, który go otworzy? Twoje zdrowie.
Andy Jones
Musisz tego spróbować. Wyobrażam sobie, że Twój klient pocztowy chciałby ustawić adres zwrotny zgodnie z jego ustawieniami.
saille
7

Jeśli używasz Mailkit . Po prostu napisz poniższy kod

string fileName = "your filename full path";
MimeKit.MimeMessage message = CreateMyMessage ();
message.WriteTo(fileName);
Naveen
źródło
0

Z jakiegoś powodu klient.send nie powiódł się (zaraz po faktycznym wysłaniu przy użyciu tej metody), więc podłączyłem dobry 'stary strumień CDO i ADODB. Musiałem również załadować CDO.message z template.eml przed ustawieniem wartości .Message. Ale to działa.

Ponieważ powyższe to C, tutaj jest jedno dla 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
źródło
Witamy w StackOverflow! Ponieważ pytanie jest z tagiem c # , odpowiedzi w innych językach nie są pomocne, przepraszam.
Hille
0

Spróbuj tego

proszę skorzystać z tych 2 odnośników (używając MailBee;) (używając 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
źródło