問題
最近同事問一個透過 SmtpClient 寄信的問題,因為客戶移機,所以將原本在 Windows 2008 x64 上的程式移到,Windows 2016 上去。
我們的程式是 .NET 3.5 ,所以在移機上並不會有什麼問題。
測試上都 OK,就只有一支執行檔在寄發 Mail 時,會發生 NullReferenceException: Object reference not set to an instance of an object. ,如下,
System.Net.Mail.SmtpConnection.GetConnection <System.NullReferenceException> 並未將物件參考設定為物件的執行個體
at System.Net.Mail.SmtpClient.Send <System.Net.Mail.SmtpException> 傳送郵件失敗。
於 System.Net.Mail.SmtpClient.Send(MailMessage message)
解法
於是寫了測試程式來測試,卻是 OK 的,如下
1 | var smpt = new System.Net.Mail.SmtpClient(); |
大家可以發現,NetworkCredential 只 Assign 使用者代號,使用者密碼是給空字串。
有些 mail server 是允許發給內部使用者時,不需要驗證的(有點像是撥打內網不用付費)。
模擬執行檔去呼叫也沒問題。
而錯誤訊息(SmtpConnection.GetConnection NullReferenceException)也叫人不知如何是好 …
正當絕望之際,忽然想到,我的測試程式預設是使用 .NET 4.6 ,而我的執行檔是 .NET 3.5 的。
於是將測試程式切到 .NET 3.5 一試,一樣的錯誤出現了 …
於是再將 NetworkCredential 的使用者代號也給空字串,再測試就沒有問題了。
以這個問題的解法有2個,
- 如果不需要驗證的話,NetworkCredential 的使用者及密碼都給空字串。
- 設定執行檔的 config ,讓它走 .NET 4.0 因為這樣子的狀況,在 .NET 4.0 是沒問題的。
<startup><supportedRuntime version=”v4.0” sku=”.NETFramework,Version=v4.0”/></startup>
嗯… 不過,為什麼舊的 Windows 2008 Server 卻不會有這種問題呢? 筆者在另一台 Windows 2008 R2 Server 上試也是 GG 。
以下是 Windows 2008 Server 上關於 .net 3.5 的更新,