วิธีบันทึกวัตถุ MailMessage ลงในดิสก์เป็นไฟล์ * .eml หรือ * .msg


88

ฉันจะบันทึกวัตถุ MailMessage ลงในดิสก์ได้อย่างไร วัตถุ MailMessage ไม่เปิดเผยเมธอด Save () ใด ๆ

ฉันไม่มีปัญหาถ้ามันบันทึกในรูปแบบใด ๆ * .eml หรือ * .msg มีความคิดอย่างไรที่จะทำสิ่งนี้?

คำตอบ:


124

เพื่อความง่ายฉันจะอ้างคำอธิบายจากรายการ Connect :

คุณสามารถกำหนดค่า SmtpClient ให้ส่งอีเมลไปยังระบบไฟล์แทนเครือข่ายได้ คุณสามารถดำเนินการทางโปรแกรมได้โดยใช้รหัสต่อไปนี้:

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

คุณยังสามารถตั้งค่านี้ในไฟล์การกำหนดค่าแอปพลิเคชันของคุณดังนี้:

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

หลังจากส่งอีเมลคุณจะเห็นไฟล์อีเมลถูกเพิ่มลงในไดเร็กทอรีที่คุณระบุ จากนั้นคุณสามารถมีกระบวนการแยกต่างหากในการส่งข้อความอีเมลในโหมดแบตช์

คุณควรจะสามารถใช้ตัวสร้างว่างแทนตัวสร้างที่อยู่ในรายการได้เนื่องจากจะไม่ส่งไป


1
ฉันพบว่าฉันต้องเพิ่ม <network host = "... " ฯลฯ นอกเหนือจากที่ Ryan ให้มาด้วย
Steven Rogers

10
มีวิธีใดในการเปลี่ยนชื่อไฟล์ของไฟล์. eml ที่ส่งออกหรือไม่ ฉันไม่ต้องการให้มีลักษณะดังต่อไปนี้: f80f4695-551c-47d7-8879-40ad89707b23.eml ขอบคุณ!
buzzzzjay

8
แม้ว่าจะเป็นโพสต์เก่า แต่ฉันต้องการเพิ่มคำตอบสำหรับคำถามสุดท้ายจาก @buzzzzjay: ดูที่นี่: ลิงค์
Corné Hogerheijde

ขอบคุณสำหรับลิงค์ที่มีประโยชน์มาก!
buzzzzjay

ดีมันได้ผลสำหรับฉัน ฉันจะเปิด Outlook เพื่อเปิดไฟล์ที่บันทึกไว้ในฝั่งไคลเอนต์ได้อย่างไร
ก่อสร้าง

29

ต่อไปนี้เป็นวิธีการขยายเพื่อแปลง MailMessage เป็นสตรีมที่มีข้อมูล EML เห็นได้ชัดว่าเป็นการแฮ็กเล็กน้อยเนื่องจากใช้ระบบไฟล์ แต่ใช้งานได้

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

จากนั้นคุณสามารถรับสตรีมที่ส่งคืนและทำตามที่คุณต้องการรวมถึงการบันทึกไปยังตำแหน่งอื่นบนดิสก์หรือจัดเก็บในฟิลด์ฐานข้อมูลหรือแม้กระทั่งการส่งอีเมลเป็นไฟล์แนบ


1
สวัสดี Saille ... รหัสของคุณทำงานได้ดีและใช่มันกำลังสร้างไฟล์ eml หรือ Msg แต่ฉันไม่สามารถเปิดได้ใน MS outlook :( ต้องการความช่วยเหลือจากคุณในการทำเช่นนั้น
Rahul Jain

2
ไฟล์. EML ควรเปิดใน Outlook แต่ถ้าไม่สามารถทำได้ให้ลองเปลี่ยนชื่อนามสกุลไฟล์เป็น. MHT จากนั้นเปิดใน Internet Explorer
saille

Saille - เป็นไปได้ไหมที่จะบันทึกโดยไม่มีที่อยู่ "จาก" จึงสามารถส่งจากผู้ใช้ที่เปิดขึ้นมาได้ ไชโย
Andy Jones

คุณต้องลอง ฉันคิดว่าโปรแกรมรับส่งเมลของคุณต้องการตั้งค่าที่อยู่ตอบกลับตามการตั้งค่า
saille

7

หากคุณกำลังใช้Mailkit เพียงเขียนโค้ดด้านล่าง

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

0

ด้วยเหตุผลใดก็ตามไคลเอนต์ส่งล้มเหลว (ทันทีหลังจากส่งจริงโดยใช้วิธีการนั้น) ดังนั้นฉันจึงเสียบ 'ole CDO และ ADODB สตรีมที่ดี ฉันยังต้องโหลด CDO.message ด้วย template.eml ก่อนตั้งค่า. ข้อความ แต่มันได้ผล

เนื่องจากตัวบนคือ C นี่คือหนึ่งสำหรับ 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)

ยินดีต้อนรับสู่ StackOverflow! เนื่องจากคำถามอยู่ในแท็กc #คำตอบในภาษาอื่นจึงไม่เป็นประโยชน์ขออภัย
Hille

0

ลองดู

โปรดใช้ข้อมูลอ้างอิง 2 รายการนี้ (โดยใช้ MailBee;) (โดยใช้ 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;
        }

    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.