2013-04-16 9 views
8

Sto tentando di inviare e-mail contenenti caratteri non ASCII utilizzando le classi SmtpClient e MailMessage.Codifica soggetto su SmtpClient/MailMessage

Sto utilizzando un servizio di mailing esterno (MailChimp) e alcune delle mie email sono state respinte dal loro server SMTP. Li ho contattato e questo è ciò che rispondevano:

Risulta l'oggetto viene codificato Base64 e quindi Quoted-Printable codificato, che generalmente dovrebbe andare bene, ma uno dei personaggi sia spezzato su due righe . Quindi, quando le righe del soggetto sono un po 'più lunghe, per essere elaborate correttamente, vengono suddivise su due righe. Quando si utilizza la stampa quotata UTF-8 in una riga dell'oggetto, non si suppone che le stringhe di caratteri siano interrotte tra le righe. Invece una linea dovrebbe essere cortocircuitata in modo che la stringa di caratteri completa rimanga insieme. In questo caso, ciò non sta accadendo, quindi la stringa di caratteri che rappresenta un singolo carattere viene interrotta su più righe, e quindi non è validamente codificata in UTF-8.

Il soggetto problematico è la seguente:

Subject: XXXXXXX - 5 personnes vous ont nommé guide 

Che è, in UTF-8/Base64:

Subject: WFhYWFhYWCAtIDUgcGVyc29ubmVzIHZvdXMgb250IG5vbW3DqSBndWlkZQ== 

Perché intestazione supererebbe una certa lunghezza massima (sono incerto se si tratta della codifica Quoted-Printable e del limite di 76 caratteri per riga o del limite dell'intestazione SMTP), dopo la codifica e la divisione, l'intestazione diventerà:

Subject: =?utf-8?B?WFhYWFhYWCAtIDUgcGVyc29ubmVzIHZvdXMgb250IG5vbW3D?= 
=?utf-8?B?qSBndWlkZQ==?= 

Apparentemente ciò causa un problema durante la decodifica (poiché la prima riga non può essere decodificata su una stringa valida). Non sono sicuro di comprendere appieno il problema e ho le seguenti domande:

  • Perché il? Utf-8? B? parte ripetuta? Non dovrebbe accadere la codifica QP prima di dividere la linea e quindi la sua intestazione non dovrebbe essere ripetuta?
  • Dopo la decodifica QP, non dovremmo finire con una stringa Base64 valida a 1 riga?
  • C'è uno spazio all'inizio della seconda linea che è al di fuori della codifica QP, potrebbe essere questo il problema?
  • L'encoder è guasto o è il decodificatore?

Si noti inoltre che alcuni altri server SMTP accetteranno questo messaggio, sebbene ciò non significhi che sia valido.

Come soluzione alternativa, ho provato a disabilitare la codifica Base64, che a quanto pare non è necessaria, tuttavia la classe MailMessage ha una proprietà BodyTransferEncoding che controlla questa codifica, ma solo per la parte del corpo del messaggio. Nessuna proprietà sembra controllare la codifica "trasferimento" dell'oggetto.

risposta

5

Ciò è confermato come un bug nei forum MSDN:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/4d1c1752-70ba-420a-9510-8fb4aa6da046/subject-encoding-on-smtpclientmailmessage

E un bug è stato depositato su Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/785710/mailmessage-subject-incorrectly-encoded-in-utf-8-base64

Un work-around è quello di impostare la SubjectEncoding del MailMessage a un'altra codifica, come ISO-8859-1.In questo caso, il soggetto sarà codificato in Quoted Printable (non Base64) che evita il problema.

+0

Il work-around non funziona per me. I miei caratteri non-ascii appaiono ancora come "simboli dall'aspetto strano" nell'oggetto. :( – PussInBoots

+0

Potresti avere un problema diverso: il mio non era con caratteri strani, ma le e-mail venivano rifiutate da alcuni server SMTP. –

+0

oh ok, bello sapere. – PussInBoots

0

La mia soluzione a questo problema è una specie di trucco!

Io uso la lingua persiana nell'oggetto della posta e invio la mia posta utilizzando SmtpClient in .Net framework 4.5.2. l'oggetto del messaggio ricevuto mostra alcune parole spazzatura in determinate posizioni, ad esempio il 18 ° e il 38 ° carattere nella stringa dell'oggetto. qualunque sia il soggetto.

Poi ho provato ad inserire degli spazi (carattere 32) in queste posizioni e dopo aver inviato nuovamente la posta il risultato è stato molto buono. il soggetto unicode stava mostrando come previsto.

così ho scritto una funzione per inserire 6 posti nei miei posizione desiderata (evitando l'inserimento di spazi all'interno delle parole) come questo:

private static string InsertSpacesBetweenWords(this string subject , int where) 
    { 
     int l; 
     int i=1; 
     string[] s = subject.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 
     string output = ""; 

     if (s.Length > 0) output += s[0] + " "; 
     l = output.Length; 
     bool done = false; 

     while (i < s.Length) 
     { 
      if (!done) 
      { 
       if ((s[i] + output).Length > where) 
       { 
        for (int j = output.Length; j < where + 6; j++) 
         output += " "; 
        done = true; 
       } 
      } 
      output += s[i] + " "; 
      i++; 
     } 
     return output; 
    } 

poi ho convertito la posta soggetto di utilizzare questa funzione:

mail.Subject = mySubject.InsertSpacesBetweenWords(38).InsertSpacesBetweenWords(18); 

Il punto interessante è che Gmail e Yahoo (e forse altri sistemi di posta basati sul web) ignorano gli spazi extra e mostrano l'argomento come previsto.

0

Una soluzione migliore è utilizzare Encoding.Unicode anziché per SubjectEncoding.

Sembra che, poiché l'implementazione Microsoft ignora semplicemente la realtà dell'UTF-16 in grado di codificare i caratteri in più di due byte (come visto su Why does C# use UTF-16 for strings?), la dimensione del carattere stabile aiuta.

L'ho visto usato su https://gist.github.com/dbykadorov/9047455.

Problemi correlati