Cómo guardar el objeto MailMessage en el disco como archivo * .eml o * .msg

87

¿Cómo guardo el objeto MailMessage en el disco? El objeto MailMessage no expone ningún método Save ().

No tengo ningún problema si se guarda en cualquier formato, * .eml o * .msg. ¿Alguna idea de cómo se hace esto?

Ashwnacharya
fuente

Respuestas:

123

Para simplificar, solo citaré una explicación de un elemento de Connect :

De hecho, puede configurar SmtpClient para enviar correos electrónicos al sistema de archivos en lugar de a la red. Puede hacerlo mediante programación utilizando el siguiente código:

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

También puede configurar esto en el archivo de configuración de su aplicación de esta manera:

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

Después de enviar el correo electrónico, debería ver que los archivos de correo electrónico se agregan al directorio que especificó. Luego, puede hacer que un proceso separado envíe los mensajes de correo electrónico en modo por lotes.

Debería poder usar el constructor vacío en lugar del que aparece en la lista, ya que no lo enviará de todos modos.

Ryan Versaw
fuente
1
Descubrí que también necesitaba agregar <network host = "...", etc. además de lo que Ryan proporcionó.
Steven Rogers
10
¿Hay alguna forma de cambiar el nombre del archivo .eml de salida? Preferiría que no se pareciera a lo siguiente: f80f4695-551c-47d7-8879-40ad89707b23.eml ¡Gracias!
buzzzzjay
8
Aunque es una publicación antigua, me gustaría agregar una respuesta a la última pregunta de @buzzzzjay: eche un vistazo aquí: enlace
Corné Hogerheijde
Gracias por el enlace, ¡eso es realmente útil!
buzzzzjay
bueno, me funciona. Además, ¿cómo puedo abrir Outlook para abrir un archivo guardado en el lado del cliente?
Builder
29

Aquí hay un método de extensión para convertir un MailMessage en una secuencia que contiene los datos EML. Obviamente, es un truco ya que usa el sistema de archivos, pero funciona.

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

A continuación, puede tomar la transmisión que se devuelve y hacer lo que desee con ella, incluido guardar en otra ubicación en el disco o almacenar en un campo de base de datos, o incluso enviar por correo electrónico como un archivo adjunto.

Saille
fuente
1
Hola Saille ... Su código funciona bien y sí, está creando el archivo eml o Msg, pero no puedo abrirlo en MS Outlook :( Necesito su ayuda para hacerlo.
Rahul Jain
2
El archivo .EML debería abrirse en Outlook, pero si no puede, intente cambiar el nombre de la extensión del archivo a .MHT, luego ábralo en Internet Explorer.
Saille
Saille - ¿Es posible guardar sin una dirección "de", para que pueda ser enviado desde el usuario que lo abre? Salud.
Andy Jones
Tendrías que probarlo. Imagino que su cliente de correo querrá configurar la dirección de respuesta de acuerdo con su configuración.
Saille
7

Si está utilizando Mailkit . Solo escribe el código debajo

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

Por una razón u otra, el client.send falló (justo después de un envío real usando ese método), así que conecté un buen flujo de CDO y ADODB. También tuve que cargar CDO.message con un template.eml antes de configurar los valores de .Message. Pero funciona.

Dado que el anterior es C, aquí hay uno para 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
fuente
¡Bienvenido a StackOverflow! Como la pregunta tiene la etiqueta c # , las respuestas en otros idiomas no son útiles, lo siento.
Hille
0

prueba esto

por favor use estas 2 referencias (usando MailBee;) (usando 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
fuente