How do I save MailMessage object to the disk? The MailMessage object does not expose any Save() methods.
I dont have a problem if it saves in any format, *.eml or *.msg. Any idea how to do this?
How do I save MailMessage object to the disk? The MailMessage object does not expose any Save() methods.
I dont have a problem if it saves in any format, *.eml or *.msg. Any idea how to do this?
For simplicity, I'll just quote an explanation from a Connect item:
You can actually configure the SmtpClient to send emails to the file system instead of the network. You can do this programmatically using the following code:
SmtpClient client = new SmtpClient("mysmtphost"); client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory; client.PickupDirectoryLocation = @"C:\somedirectory"; client.Send(message);
You can also set this up in your application configuration file like this:
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\somedirectory" />
</smtp>
</mailSettings>
</system.net>
</configuration>
After sending the email, you should see email files get added to the directory you specified. You can then have a separate process send out the email messages in batch mode.
You should be able to use the empty constructor instead of the one listed, as it won't be sending it anyway.
Here's an extension method to convert a MailMessage to a stream containing the EML data. Its obviously a bit of a hack as it uses the file system, but it works.
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);
}
}
}
You can then take the stream thats returned and do as you want with it, including saving to another location on disk or storing in a database field, or even emailing as an attachment.
If you are using Mailkit. Just write below code
string fileName = "your filename full path";
MimeKit.MimeMessage message = CreateMyMessage ();
message.WriteTo(fileName);
With the help of community I came up with an solution for .NET 5. I have combined this old solution with suggestions in this post and got inspired by Mailkit which resulted in nice extension method without unnecessary dependencies
public static class MailMessageHelper
{
public static void WriteTo(this MailMessage mail, Stream stream)
{
Assembly assembly = typeof(SmtpClient).Assembly;
Type _mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
// Get reflection info for MailWriter contructor
ConstructorInfo _mailWriterConstructor =
_mailWriterType.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { typeof(Stream), typeof(bool) },
null);
// Construct MailWriter object with our FileStream
object _mailWriter =
_mailWriterConstructor.Invoke(new object[] { stream, true });
// Get reflection info for Send() method on MailMessage
MethodInfo _sendMethod =
typeof(MailMessage).GetMethod(
"Send",
BindingFlags.Instance | BindingFlags.NonPublic);
// Call method passing in MailWriter
_sendMethod.Invoke(
mail,
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new object[] { _mailWriter, true, true },
null);
// Finally get reflection info for Close() method on our MailWriter
MethodInfo _closeMethod =
_mailWriter.GetType().GetMethod(
"Close",
BindingFlags.Instance | BindingFlags.NonPublic);
// Call close method
_closeMethod.Invoke(
_mailWriter,
BindingFlags.Instance | BindingFlags.NonPublic,
null,
Array.Empty<object>(),
null);
}
}
Usage
MailMessage mail = new(mailFrom, mailTo, mailSubject, mailContent);
mail.WriteTo(new FileStream(@"path_to_file\new_mail.eml", FileMode.Create));
Also if you are using MemoryStream
and want to get result in string
, just change the return type of the extension method and at the end write
return Encoding.ASCII.GetString(stream.ToArray());
Enjoy
For one reason or another the client.send failed (right after an actual send using that method) so I plugged in good 'ole CDO and ADODB stream. I also had to load CDO.message with a template.eml before setting the .Message values. But it works.
Since the above one is C here is one for 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)
try this
please use these 2 reference ( using MailBee;) ( using 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;
}
}
© 2022 - 2024 — McMap. All rights reserved.