11.881 messaggi dal 09 febbraio 2002
Contributi
Non con i tick, ma con un Guid in modo da evitare eventuali collisioni. Oppure con Path.GetTempFileName().
var file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
File.WriteAllBytes(file, bytes);
//Qii alleghi
//Qui invii la mail
//E alla fine elimini
File.Delete(file);



adesso ho scaricato la libreria provo a guardare il costruttore...

Quando la libreria si aggiorna per motivi di sicurezza la riscarichi e rifai la modifica? Se non altro segnala la modifica all'autore, in modo che la incorpori nella sua codebase.
Modificato da BrightSoul il 19 luglio 2018 18.03 -

Enjoy learning and just keep making
3.920 messaggi dal 28 gennaio 2003
Allora, la questione di creare un file io l'ho usata tempo fa in altro contesto. Basta assegnare come nome un guid.
Per la pulizia avevo fatto una routine che cancellava i file della data directory, più vecchi di un certo tempo prefissato. E ho visto che funzionava.

Per quanto riguarda la libreria, in effetti ho aggiunto il costruttore che accetta uno stream e un nome, ma la cosa non è così banale, tanto che non mi funziona. Se riuscite, mandate la soluzione.

ciao

Pietro
11.881 messaggi dal 09 febbraio 2002
Contributi
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 -

Enjoy learning and just keep making
3.920 messaggi dal 28 gennaio 2003
Interessante!

Però, se riesci a modificare la libreria, anche per la questione di accettare file con nome con spazi, non dimenticarti di noi!

ciao.

Pietro
224 messaggi dal 20 novembre 2014
BrightSoul ha scritto:
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 -


Grazie Moreno,
instancabile come sempre, ho provato a caricare la tua classe ma ho un errore che mi si presenta in forme diverse da ieri.
Mi segnala l'errore nel costruttore

private TemporaryFile(string fullPath)
        {
            FullPath = fullPath;
        }


dicendomi: "Impossibile assegnare un valore alla proprietà o all'indicizzazione 'TestNet.Controllers.TemporaryFile.FullPath' perchè è in sola lettura"

ho avuto lo stesso errore quando ieri ho provato a modificare il costruttore della libreria... ma dove sbaglio?
Grazie anticipate
224 messaggi dal 20 novembre 2014
ok, lascia stare, mancava

public string FullPath { get; set; }
11.881 messaggi dal 09 febbraio 2002
Contributi
Nelle versioni recenti di C#, se il set manca puoi comunque assegnare un valore alla proprietà dal costruttore. In pratica è come se fosse una proprietà "readonly".

Nel tuo caso metti un private set, in modo che il FilePath non possa essere modificato dall'esterno.
public string FullPath { get; private set; }


ciao,
Moreno

Enjoy learning and just keep making
11.881 messaggi dal 09 febbraio 2002
Contributi
Ecco qua la libreria modificata:
https://sourceforge.net/u/brightsoul80/netimplicitssl/ci/master/tree/

Ho mandato una pull request all'autore ma vedo che ce ne sono altre appese da 2 mesi.
Se la dovete usare in produzione, prima testatela adeguatamente, perché io ho scritto questo codice mentre ero in mutante sul divano mentre a voi serve per lavorare.

Funzionalità aggiunte:
  • Supportati MimeAttachment basati su Stream;
  • Supportati allegati con nomi contenenti spazi;
  • Fix di un bug che si verificava con SubjectEncoding null.


Di nuovo, il mio consiglio è di NON usare questa libreria modificata ma l'altra soluzione che ho postato ieri. Solo se e solo dopo che questa pull request sarà stata accetta dall'autore e rilasciata una nuova versione del pacchetto NuGet, allora è il caso di usarla.

ciao,
Moreno

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.