解決 OpenSMTP.Net 信件主旨過長,會變成亂碼的問題

OpenSMTP.Net 是 .Net 平台下一個免費、open source 的 SMTP 元件,中文的介紹可以參考 Neo's Blog免費的 .Net Email 元件一文介紹。

最近在使用 OpenSMTP.Net 來發信上遇到了問題,就是只要信件主旨一太長,超過十二個全型字,那使用者收到的信件就會是一堆亂碼。

有興趣的朋友可以用下列的程式碼測看看︰

Dim from As New EmailAddress("from@abc.com", "From")
Dim sto As New EmailAddress("to@abc.com", "to")
Dim msg As New OpenSmtp.Mail.MailMessage(from, sto)
msg.Subject = "一二三四五六七八九十一二三"
msg.Body = "內文"
msg.Charset = "big5"

Dim Smtp As New Smtp("smtp.abc.com", 25)
Smtp.Username = "username" '有支援 SMTP 認證
Smtp.Password = "password"
Smtp.SendMail(msg)

今天總算找到瞭解決這問題的方式,詳細說明可以參考 haogj 關於 OpenSmtp 郵件標題過長後出現亂碼問題的解決一文的說明。在這邊記錄一下 patch 程式的步驟︰

1. 到 OpenSMTP.Net 官網下載最後 release 的 source code,目前最後的版本為 01.11.0 版。

2. 解壓縮後,開啟 src/MailEncoder.cs 檔,加入下方的 function︰

public static string ConvertHeaderToBase64(string s, string charset)
{
  int lineLength = 40;
  Encoding encoding = Encoding.GetEncoding(charset);
  byte[] buffer = encoding.GetBytes(s);
  StringBuilder sb = new StringBuilder();
  string linebase64;
  int block = buffer.Length % lineLength == 0 ? buffer.Length / lineLength : buffer.Length / lineLength + 1;
  for (int i = 0; i < block; i++)
  {
    if (buffer.Length - i * lineLength >= lineLength)
      linebase64 = Convert.ToBase64String(buffer, i * lineLength, lineLength);
    else
      linebase64 = Convert.ToBase64String(buffer, i * lineLength, buffer.Length - i * lineLength);
    sb.Append("=?");
    sb.Append(charset);
    sb.Append("?B?");
    sb.Append(linebase64);
    sb.Append("?=\r\n\t");
  }
  sb.Remove(sb.Length - 3, 3);
  return sb.ToString();
}

3. 開啟 src/MailMessage.cs 檔,在 toString() function 中,將下列這一行 source code 註解起來︰

//sb.Append("Subject: " + MailEncoder.ConvertHeaderToQP(cleanSubject.ToString(), charset) + "\r\n");

改成這一行︰

sb.Append("Subject: " + MailEncoder.ConvertHeaderToBase64(cleanSubject.ToString(), charset) + "\r\n");

4. 在 src/ 目錄下,以下列命令重新 compile OpenSMTP

csc.exe /o+ /nologo /warn:3 /checked /t:library /out:..\bin\OpenSmtp.dll /doc:..\OpenSmtp.xml *.cs

5. 在 bin/ 目錄下就可以得到重編過的 OpenSMTP.dll 檔,用它來取代原本的 dll 檔就可以解決這個問題了。

1 意見:

匿名 提到...

您好
我有試過您的方法
但還是出現亂碼,您方便把改過的Code
跟編譯過的dll寄給我嗎?
wong@mail2000.com.tw
謝謝你!