Questa è la mia soluzione. Per nessun motivo mi metterei a modificare la libreria per usarla in produzione. Nel tempo libero farei un fork del repository della libreria per aggiungere un costruttore a MimeAttachment che accetta uno Stream. Poi manderei una pull request all'autore della libreria. Solo dopo che la pull request è stata accettata e una nuova versione del pacchetto NuGet è stata rilasciata allora, solo a quel punto, userei il costruttore che accetta lo Stream. Ma fino a quel momento, ecco:
//In questo esempio imposto il byte array a mano. Nel caso reale arriverà da altra fonte (es. upload)
byte[] content = Encoding.UTF8.GetBytes("Ciao questo è il testo dell'allegato");
//Idem per il destinatario: arriva probabilmente dal form ma per motivi di demo lo leggo dall'appsettings
string to = ConfigurationManager.AppSettings["To"];
using (MimeMailMessage msg = new MimeMailMessage())
{
msg.From = new MailAddress(ConfigurationManager.AppSettings["From"]);
msg.To.Add(new MailAddress(to));
msg.Subject = "Test email";
msg.Body = "L'ora esatta è " + DateTime.Now.ToString();
msg.IsBodyHtml = true;
using (var tempFile = TemporaryFile.FromByteArray(content, "allegato.txt"))
{
using (var attachment = new MimeAttachment(tempFile, new ContentType("text/plain"), AttachmentLocation.Attachmed))
{
msg.Attachments.Add(attachment);
using (var mailer = new MimeMailer(ConfigurationManager.AppSettings["Host"], int.Parse(ConfigurationManager.AppSettings["Port"])))
{
mailer.User = ConfigurationManager.AppSettings["Username"];
mailer.Password = ConfigurationManager.AppSettings["Password"];
mailer.SslType = SslMode.Ssl;
mailer.AuthenticationMode = AuthenticationType.Base64;
mailer.SendMail(msg);
}
}
}
}
IMPORTANTE: usare i blocchi using sugli oggetti che implementano IDisposable!
TemporaryFile è una mia classe implementata come segue. Il suo scopo è scrivere un file temporaneo a partire da un byte array, per poi eliminarlo al termine dell'utilizzo. Il file verrà eliminato anche se dovesse verificarsi un'eccezione durante l'invio, quindi non c'è bisogno di timer che eliminano periodicamente vecchi file.
public class TemporaryFile : IDisposable
{
private TemporaryFile(string fullPath)
{
FullPath = fullPath;
}
public static TemporaryFile FromByteArray(byte[] content, string desiredFilename)
{
var parentDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
//Se su aruba non funziona, provare questo:
//var parentDirectory = Path.Combine(HostingEnvironment.MapPath("~/App_Data/"), Guid.NewGuid().ToString());
Directory.CreateDirectory(parentDirectory);
var fullPath = Path.Combine(parentDirectory, desiredFilename);
File.WriteAllBytes(fullPath, content);
return new TemporaryFile(fullPath);
}
public string FullPath { get; }
public void Dispose()
{
File.Delete(FullPath);
var parentDirectory = Path.GetDirectoryName(FullPath);
Directory.Delete(parentDirectory);
}
public static implicit operator string(TemporaryFile file)
{
return file.FullPath;
}
}
Modificato da BrightSoul il 19 luglio 2018 21.56 -