2013-04-05 5 views
9

Iam utilisant l'API Amazon SendSawEmail d'EOS d'où j'ai besoin d'un MailMessage en tant que Memorystream.C# MailMessage au flux - problème de codage

J'ai trouvé plusieurs réponses au problème MailMessage to MemoryStream ici sur stackoverflow.

Solution 1: En utilisant celui qui utilise des méthodes privées, il en résulte un mauvais encodage des parties de l'e-mail: https://stackoverflow.com/a/8826833

Solution 2: Pas de problème d'encodage en utilisant cette solution lorsque vous envoyez à un pick-up répertoire, puis le relire en: https://stackoverflow.com/a/14350088

Je n'aime pas du tout le fait que j'ai besoin d'écrire dans un fichier temporaire pour que cela fonctionne correctement. Quelqu'un a-t-il une idée de la façon dont la pure solution MemoryStream peut gâcher une partie de l'encodage?

Le test de courrier de message avec iam est ceci:

var mailMessage = new MailMessage(); 
mailMessage.Subject = "HEADER WITH SPECIAL ÆØÅ"; 
mailMessage.Body = "TEST"; 

Attachment att = new Attachment(@"C:\AttachmentWithSpecial ÆØÅ.pdf"); 
mailMessage.Attachments.Add(att); 
mailMessage.From = new MailAddress("[email protected]", "NameÆØÅ"); 
mailMessage.To.Add(new MailAddress("[email protected]", "NameÆØÅ")); 

Pour résumer:

  • Si je vous envoie ce message avec SMTP standard, il semble bon.
  • Si je l'envoie à l'aide SendRawEmail il semble bon si je généré MemoryStream en utilisant une solution 2
  • Si je l'envoie à l'aide SendRawEmail il a des problèmes d'encodage si je généré MemoryStream en utilisant la solution 1.

avec les problèmes de l'encodage, je veux dire « ø » montrant que

enter image description here

+0

Pourquoi ne pas utiliser SendEmail à la place? SES vous permet de composer des emails et il supporte l'encodage. –

+0

Comme je le vois, il ne supporte pas les pièces jointes. ? –

+0

Oh oui, avez-vous essayé d'utiliser StringWriter? Le flux de mémoire peut ignorer l'encodage car il utilise des octets comme stockage. –

Répondre

1

Avez-vous essayé de spécifier explicitement le codage pour le sujet/corps et MailAddress?

je suppose que lorsque .NET écrit mails au dossier, il peut en quelque sorte de définir le bon encodage (ou peut-être File Reader en quelque sorte peut trouver le bon encodage pour convertir les données). Et en mémoire, tout est codé par défaut, ce qui ne fonctionne pas pour vous.

+0

Ya j'ai essayé cela cependant. NET j'ai vraiment très intelligent sur la mise en UTF-8 si nécessaire. Dans le constructeur d'une adresse mail pour l'instance, vous trouvez: this.displayNameEncoding = displayNameEncoding ?? Encoding.GetEncoding ("utf-8"); Ce qui signifie que si vous ne définissez pas d'encodage, il sera par défaut UTF-8. Dans l'ensemble du sujet et du corps, ils ont un test de code pour savoir si une chaîne contient uniquement des ascii, sinon elle essaiera de deviner elle-même le codage. Donc, si vous le faites, mail.Subject = "æøå"; puis vérifiez le mail.SubjectEncoding il sera correctement déjà UTF-8 –

0
message.BodyEncoding = message.SubjectEncoding = message.HeadersEncoding = Encoding.UTF8; 
0

Malheureusement l'objet MailMessage est bogué et a une interface médiocre.

La bonne chose est que 4,5 .NET partiellement fixé avec le drapeau allowUnicode Envoyer() (malheureusement Envoyer méthode est encore privée)

Ci-dessous est modifié « Solution 1 ». Il code le sujet de la même manière que "Solution 2". .NET Framework 4.5 uniquement.

private static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message) 
{ 
    Assembly systemAssembly = typeof(SmtpClient).Assembly; 
    Type mailWriterType = systemAssembly.GetType("System.Net.Mail.MailWriter"); 
    const BindingFlags nonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic; 
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(nonPublicInstance, null, new[] typeof(Stream) }, null); 

    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", nonPublicInstance); 
    MethodInfo closeMethod = mailWriterType.GetMethod("Close", nonPublicInstance); 
    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     object mailWriter = mailWriterContructor.Invoke(new object[] { memoryStream }); 
     //AssertHelper.IsTrue(sendMethod.GetParameters().Length > 2, ".NET framework must be 4.5 or higher in order to properly encode email subject."); 
     sendMethod.Invoke(message, nonPublicInstance, null, 
      new[] { mailWriter, true, false }, 
      null); 
     closeMethod.Invoke(mailWriter, nonPublicInstance, null, new object[] { }, null); 
     return memoryStream; 
    } 
}