這可能只是我,但在我看來,System.Net.Mail類已經這樣做了抽象的細節一個良好的工作和罷工的可定製性和易用性之間的良好平衡。如果您嘗試簡化更多,您將失去在需要時自定義的能力。
我們開始沿着這條道路做電子郵件,當我們做了更多的項目,並且我們的需求改變了,我們最終不得不定製我們的班級,以至於顯然整個練習是浪費時間。
但是,我知道你來自哪裏,這裏有另一種統一如何從應用程序發送電子郵件的可能性。這不是你要求的,而是根據我們團隊的工作原理,以一種可能的不同方式來處理問題。
我們的決定基於SOLELY對我們最大的痛點,那就是我們的管理員每隔幾年就會換出Exchange服務器,或者他們會因爲某種原因更改IP地址。每次發生這種情況時,我們都必須重新編譯一堆代碼,這非常令人沮喪。
我們最終設置了一個具有電子郵件功能的Web服務。現在,我們內部應用中的所有電子郵件都使用Web服務。當我們的管理員更改服務器上的某些內容時,我們只需要調整Web服務中的.config文件,而不必在每個發送電子郵件的應用程序中重新編譯或編輯.config。
這對我們特別有效,因爲我們能夠將錯誤處理集成到我們的中央錯誤記錄數據庫中,所以我們所有的應用程序都只有幾行代碼來發送電子郵件。錯誤處理是免費的。
自從我們實現這個以來,唯一必須做的調整是讓Web服務通過PickupDirectory發送電子郵件,而不是直接與Exchange服務器通信。這允許服務在Exchange服務器關閉時進行工作(維護,重新啓動以應用修補程序等)。)
Web服務中的代碼也相當簡單,並使用Microsoft.Security.AntiXss組件處理衛生。
代碼中對監督系統的引用是對我們的中央錯誤記錄數據庫的引用。我不打算包含該代碼,因爲這已經太長了答案,而且它確實會將錯誤記錄到SQL數據庫。
對不起,它是在你指定C#的VB中,但如果你有興趣,它應該很容易轉換。
<WebMethod()> _
Public Function SendEmailViaPickupDir(ByVal FromAddress As String, ByVal ToList As String, ByVal CcList As String, ByVal BccList As String, _
ByVal Subject As String, ByVal MessageBody As String, ByVal IsBodyHtml As Boolean) As Boolean
Dim msg As System.Net.Mail.MailMessage = BuildMessage(FromAddress, ToList, CcList, BccList, Subject, MessageBody, IsBodyHtml)
If Not msg Is Nothing Then
Return SendMessageViaPickupDir(msg)
Else
Return False
End If
End Function
Private Function BuildMessage(ByVal FromAddress As String, ByVal ToList As String, ByVal CcList As String, ByVal BccList As String, _
ByVal Subject As String, ByVal MessageBody As String, ByVal IsBodyHtml As Boolean) As System.Net.Mail.MailMessage
Dim msg As New System.Net.Mail.MailMessage
Try
msg.From = New System.Net.Mail.MailAddress(FromAddress)
If Not ToList Is Nothing Then
For Each Address As String In ToList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
msg.To.Add(New System.Net.Mail.MailAddress(Address.Trim()))
Next
End If
If Not CcList Is Nothing Then
For Each Address As String In CcList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
msg.CC.Add(New System.Net.Mail.MailAddress(Address.Trim()))
Next
End If
If Not BccList Is Nothing Then
For Each Address As String In BccList.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
msg.Bcc.Add(New System.Net.Mail.MailAddress(Address.Trim()))
Next
End If
msg.Subject = Microsoft.Security.Application.AntiXss.HtmlEncode(Subject)
If (IsBodyHtml) Then
msg.Body = Microsoft.Security.Application.AntiXss.GetSafeHtmlFragment(MessageBody)
Else
' This was causing formatting issues...
msg.Body = MessageBody
End If
msg.IsBodyHtml = IsBodyHtml
Catch ex As Exception
Dim s As New OverseerService
s.WriteToSql(Convert.ToInt64(ConfigurationManager.AppSettings("OverseerWebSiteResourceid")), User.Identity.Name, _
My.Computer.Name, ex.ToString(), MyCompany.Overseer.EventLogger.SeverityLevel.Critical)
Return Nothing
End Try
Return msg
End Function
Private Function SendMessageViaPickupDir(ByVal msg As System.Net.Mail.MailMessage) As Boolean
Dim ret As Boolean = False
Try
' try to send through pickup dir
Dim c1 As New System.Net.Mail.SmtpClient("localhost")
c1.DeliveryMethod = Net.Mail.SmtpDeliveryMethod.PickupDirectoryFromIis
c1.Send(msg)
ret = True
Catch ex As Exception
Try
' log as a known error
Dim s As New OverseerService
s.WriteToSql(Convert.ToInt64(ConfigurationManager.AppSettings("OverseerWebSiteResourceid")), User.Identity.Name, _
My.Computer.Name, "failed to write email to pickup dir " + ex.ToString(), MyCompany.Overseer.EventLogger.SeverityLevel.KnownError)
Catch
' ignore error from writing the error
End Try
End Try
Return ret
End Function
戴夫 - 我喜歡這個想法使用的Web服務。我想如果我通過數據庫發送電子郵件,我可以實現更靈活的架構設計。我也可以將我的電子郵件提供商設計也納入其中。你怎麼看? – DotNetDude
您可能可以通過電子郵件發送數據庫。我不知道這是否會是更好的選擇。我必須嘗試調查。我們幾乎堅持這種設計,因爲它消除了我們所有的痛苦,並且對我們來說工作得非常好,但是如果您想進一步改進它,那麼您會獲得更多的權力! – David
好的感謝您的回覆! – DotNetDude