2013-04-16 11 views
8

Próbuję wysyłać wiadomości e-mail zawierające znaki spoza zestawu ASCII przy użyciu klas SmtpClient i MailMessage.Kodowanie obiektu w SmtpClient/MailMessage

Korzystam z zewnętrznej usługi pocztowej (MailChimp), a niektóre z moich e-maili zostały odrzucone przez ich serwer SMTP. I skontaktował się z nimi i to, co oni odpowiedzieli:

Wydaje linia przedmiotem jest Base64 zakodowane i następnie quoted-printable kodowane, co generalnie powinno być dobrze, ale jeden z bohaterów jest złamany w dwóch liniach . Jeśli więc linie tematyczne są nieco dłuższe, aby je poprawnie przetworzyć, są podzielone na dwie linie. Podczas używania cytowanego w temacie UTF-8 do wydrukowania w wierszu tematu, ciągi znaków nie powinny być przerywane między wierszami. Zamiast tego należy skrócić linię, aby cały łańcuch znaków pozostał razem. W tym przypadku tak się nie dzieje, więc ciąg znaków, który reprezentuje pojedynczy znak, jest łamany w wielu wierszach i dlatego nie jest poprawnie zakodowany w formacie UTF-8, który można wydrukować.

Problematyczny przedmiotem jest następujący:

Subject: XXXXXXX - 5 personnes vous ont nommé guide 

Który jest w UTF-8/Base64:

Subject: WFhYWFhYWCAtIDUgcGVyc29ubmVzIHZvdXMgb250IG5vbW3DqSBndWlkZQ== 

Bo nagłówek przekroczy pewną maksymalną długość (jestem pewien niezależnie od tego, czy jest to kodowanie z możliwością zadeklarowania do druku, czy ograniczenie do 76 znaków w linii lub limit nagłówka SMTP), po kodowaniu i dzieleniu nagłówek stanie się:

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

Podobno powoduje to problem podczas dekodowania (ponieważ pierwszego wiersza nie można odszyfrować do poprawnego ciągu znaków). Nie jestem pewien, czy w pełni rozumiem problem, i mam następujące pytania:

  • Dlaczego jest? Utf-8? B? część powtórzona? Czy kodowanie QP nie powinno się zdarzyć przed podziałem linii, a zatem jego nagłówek nie powinien się powtarzać?
  • Po dekodowaniu QP, czy nie powinniśmy otrzymać poprawnego 1-liniowego łańcucha Base64?
  • Na początku drugiej linii jest spacja, która wykracza poza kodowanie QP, czy to może być problem?
  • Czy enkoder jest uszkodzony, czy jest to dekoder?

Należy również pamiętać, że niektóre inne serwery SMTP zaakceptują tę wiadomość, ale to nie znaczy, że jest ona ważna.

W ramach obejścia problemu próbowałem wyłączyć kodowanie Base64, co wydaje się niepotrzebne, jednak klasa MailMessage ma właściwość BodyTransferEncoding, która kontroluje to kodowanie, ale tylko dla części treści wiadomości. Żadna właściwość nie wydaje się kontrolować kodowania "transferu" podmiotu.

Odpowiedz

5

Zostało to potwierdzone jako błąd w forach MSDN:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/4d1c1752-70ba-420a-9510-8fb4aa6da046/subject-encoding-on-smtpclientmailmessage

A to błąd został złożony na Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/785710/mailmessage-subject-incorrectly-encoded-in-utf-8-base64

Jeden obejście jest ustawienie SubjectEncoding z MailMessage do inne kodowanie, takie jak ISO-8859-1.W takim przypadku temat zostanie zakodowany w Quoted Printable (nie Base64), co pozwala uniknąć problemu.

+0

Obejście problemu nie działa dla mnie. Moje nie-ascetyczne postacie wciąż pojawiają się jako "dziwacznie wyglądające symbole" w temacie. :( – PussInBoots

+0

Możesz mieć inny problem.Mine nie było z dziwnie wyglądającymi postaciami, ale wiadomości e-mail są odrzucane przez niektóre serwery SMTP. –

+0

o tak, dobrze wiedzieć. – PussInBoots

0

Moje rozwiązanie tego problemu to jakaś sztuczka!

Używam języka perskiego w temacie wiadomości e-mail, a ja wysyłam swoją pocztę przy użyciu SmtpClient w .Net framework 4.5.2. odebrany temat wiadomości pokazuje niektóre wyrzucone słowa w określonych pozycjach np. 18. i 38. znak w temacie. niezależnie od tematu.

Potem próbowałem wstawić spacje (znak 32) w tych pozycjach i po ponownym wysłaniu maila wynik był bardzo dobry. temat unicode był wyświetlany zgodnie z oczekiwaniami.

więc pisał funkcję wkładki 6 przestrzenie w moich wymaganej pozycji (unikając wstawienie miejsca wewnątrz słowa), jak poniżej:

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; 
    } 

następnie konwertowane poczty przedmiotu za pomocą tej funkcji:

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

Interesujące jest to, że poczta Gmail i Yahoo (i ewentualnie inne internetowe systemy pocztowe) ignorują dodatkowe spacje i pokazują temat zgodnie z oczekiwaniami.

0

Lepszym rozwiązaniem jest użycie Encoding.Unicode zamiast Encoding.UTF8 dla SubjectEncoding.

Wygląda na to, że ponieważ implementacja Microsoftu po prostu ignoruje rzeczywistość, w której kodowanie znaków w więcej niż dwóch bajtach (zgodnie z Why does C# use UTF-16 for strings?) UTF-16 pomaga w stabilnym rozmiarze znaków.

Widziałem to używane na https://gist.github.com/dbykadorov/9047455.