如下圖,主旨太長就被截斷
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyET-qn_9Mkw34aCLgQ_5ABGlLxHIEiGb4Kb_fFNL1tXeDzpGO2v_dyxsjJY6YbZSH41noDMy3bwjs4BzOUleQPZQu3xqqx9jOSR18ZBCGP3mDAPmPbo77gN-UDVk3vcahVV_Ab9ry4Lj1/s640/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7_2016-06-04_13_36_13.png)
An 'encoded-word' may not be more than 75 characters long
看樣子要嘛就是 Zimbra 處理的時候有問題,要嘛就是 System.Net.Mail 發信的時候處理有問題。
顯示信件原始內容來看,直接拿 subject 裡最後一行去解 Base64 會發現有亂碼!
解回來的內容開頭是亂碼:
問題追到這邊大概有答案了,就是 System.Net.Mail 雖然會幫我們處理不能超過 75 個字元的問題,但是沒有考慮到雙位元的文字處理,而 Zimbra 分段去處理主旨的編碼,就會造成中文字被分割成兩個半的問題。
所以追一下 System.Net.Mail 的 Source Code 會發現,如果自己處理掉編碼換行這段,System.Net.Mail 就會以我們處理過的原封不動丟出去。
雖然這邊註解是說會 re-encode before sending ,但是再往 DecodeHeaderValue 裡面看,會發現,他只處理 Base64 編碼過的,如果是又做過 75 個字元切段又做 Base64 的話,他就會直接放棄 re-encode 。
用 ? 去切字串,如果切出來不是 5 個,就放棄。( MimeBasePart.cs )
所以,如果我們自己處理有考慮中文字的 75 個字元切段後再 Base64 編碼的話,應該就可以解決這個問題。
private string folding(string input) { string tempInput = input; string result = ""; const int f = 37; // 一個字一律算兩個 bytes 最長只能 75 所以 75/2 https://www.ietf.org/rfc/rfc2047.txt for (int i = 0, len = tempInput.Length; i <= len; i += f) { string x = tempInput.Substring(i, (i + f >= len ? len - i : f)); result += string.Format(@"=?UTF-8?B?{0}?=", Convert.ToBase64String(Encoding.UTF8.GetBytes(x))); } if (result.Split("?".ToCharArray()).Length == 5) result = result + "=?UTF-8?B??="; // 只切到一次還會會被解回去,所以補一個空的 return result; }