这可能只是我,但在我看来,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