2019年7月3日 星期三

[ASP.NET開發筆記]C# System.Net.Mail 郵件附件中文檔名發送失敗問題


C# System.Net.Mail 郵件附件中文檔名發送失敗問題


最近開發時在發送mail的附件上卡關,
明明在開發機上是正常的,到了正式主機時就失敗…
雖然第一個反應是版本不一致的原因,
最好的方式是開發與正式機的版本相同就不會有困擾了,
但總有個不得已…所以通常我是試看看哪個的方式
可以在二個環境都順利執行,
好處是可以挖出一些原本自已不知道的問題
壞處是要花時間找問題,趕時間時會死人…

先簡單描述一下問題:


開發機的 .NET Framework CLR 版本:4.0.30319.42000

正式主機的.NET Framework CLR 版本:4.0.30319.1022

當附件名稱設定時使用 Attachment.ContentDisposition.FileName 有中文名稱,在正式主機會失敗

改為 Attachment.Name 設定中文名稱,在開發、正式機都可以順利執行

以下是簡短的code 測試

byte[] bytes = Encoding.UTF8.GetBytes("abc");
MemoryStream memStream = new MemoryStream(bytes);

Attachment attachedFile = new Attachment(memStream, MediaTypeNames.Application.Octet);

attachedFile.ContentDisposition.FileName = "測試";  //中文字會失敗

//解法:
//(1)對附件以Base64編碼方式處理( TransferEncoding.Base64 )
//(2)改用:attachedFile.Name = "測試";



 微軟對判斷安裝的.NET Framework版本說明中提到:

CLR 版本是以 .NET Framework 應用程式執行所在的執行階段為基礎。
單一的 CLR 版本通常會支援多個 .NET Framework 版本。
例如,CLR 4.0.30319.xxxxx 版支援 .NET Framework 4 到 4.5.2 版,其中 xxxxx 會小於 42000,
而 CLR 4.0.30319.42000 版支援從 .NET Framework 4.6 起的 .NET Framework 版本。

所以 .NET Framework 4.6以上附件中文名稱使用ContentDisposition.FileName 是正常的,4 ~4.5.2 的話,如果想要用ContentDisposition.FileName可以順利過關的話,有個方法是用Base64來將檔名編碼,怎麼用Base64編碼可以參考這裡

花了點時間測了一下,不想這麼麻煩,可以試試 不要設定Attachment的ContentDisposition.FileName, 只設定 Attachment.Name 就好,這個方法可過,原理?我還沒開智慧,就偷賴結論為:版本問題吧~