Click here to Skip to main content
15,867,594 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Sending an Email in C# with or without attachments: generic routine.

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
8 Mar 2011CPOL 21.5K   2   5
These are the same classes in VB.NET in case needed.I've also made the mail server address a parameter to allow the code to be runnable on copy paste.The problem while sending the bigger files was the smtp client's timeout(default 100s). I've made this dependent on the attachments' size...
These are the same classes in VB.NET in case needed.
I've also made the mail server address a parameter to allow the code to be runnable on copy paste.
The problem while sending the bigger files was the smtp client's timeout(default 100s). I've made this dependent on the attachments' size allowing higher timeouts for bigger files.

VB.NET
Imports System.Text
Imports System.Net.Mail
Public Class SMTPMailSender
    ''' <summary>
    ''' Sends and email
    ''' </summary>
    ''' <param name="to">Message to address</param>
    ''' <param name="body">Text of message to send</param>
    ''' <param name="subject">Subject line of message</param>
    ''' <param name="fromAddress">Message from address</param>
    ''' <param name="fromDisplay">Display name for "message from address"</param>
    ''' <param name="credentialUser">User whose credentials are used for message send</param>
    ''' <param name="credentialPassword">User password used for message send</param>
    ''' <param name="attachments">Optional attachments for message</param>
    Public Shared Sub Email(ByVal mailServerAddress As String, ByVal [to] As String, ByVal body As String, ByVal subject As String, ByVal fromAddress As String, ByVal fromDisplay As String, ByVal credentialUser As String, ByVal credentialPassword As String, ByVal attachments() As MailAttachment)
        Dim host As String = mailServerAddress
        body = UpgradeEmailFormat(body) '  This  method is not completely implemented
        Try
            Dim mail As MailMessage = New MailMessage()
            mail.Body = body
            mail.IsBodyHtml = True
            mail.To.Add(New MailAddress([to]))
            mail.From = New MailAddress(fromAddress, fromDisplay, Encoding.UTF8)
            mail.Subject = subject
            mail.SubjectEncoding = Encoding.UTF8
            mail.Priority = MailPriority.Normal
            For Each ma As MailAttachment In attachments
                mail.Attachments.Add(ma.File)
            Next
            Dim Smtp As SmtpClient = New SmtpClient
            Smtp.EnableSsl = True ' This is necessary for gmail
            Smtp.Credentials = New System.Net.NetworkCredential(credentialUser, credentialPassword)
            Smtp.Host = host
            ' I am taking 1024th of the filesize in bytes and aggregating them. This gives me an ok value to deal with in sec (x1000 for ms) subject to a minimum of 100s.
             Smtp.Timeout = Math.Max(attachments.Sum(Function(Item) (DirectCast(Item, MailAttachment).Size / 1024)), 100) * 1000
            Smtp.Send(mail)
        Catch
            Dim sb As New StringBuilder(1024)
            sb.Append("\nTo:" + [to])
            sb.Append("\nbody:" + body)
            sb.Append("\nsubject:" + subject)
            sb.Append("\nfromAddress:" + fromAddress)
            sb.Append("\nfromDisplay:" + fromDisplay)
            sb.Append("\ncredentialUser:" + credentialUser)
            sb.Append("\ncredentialPasswordto:" + credentialPassword)
            sb.Append("\nHosting:" + host)
            Debug.Print(sb.ToString)
        End Try
    End Sub
    Private Shared Function UpgradeEmailFormat(ByVal body As String) As String
        ' This has to be implemented as needed. Currently doing nothing!
        Return body
    End Function
End Class


The MailAttachment Class has a new property size that is used to determine the attachment data length:

VB.NET
Imports System.IO
Imports System.Net.Mail
Imports System.Net.Mime
Public Class MailAttachment

    Private _stream As MemoryStream
    ''' <summary>
    ''' The data memory stream to use
    ''' </summary>
    Public Property Stream() As MemoryStream
        Get
            Return _stream
        End Get
        Set(ByVal value As MemoryStream)
            _stream = value
        End Set
    End Property
    Private _filename As String
    ''' <summary>
    ''' Gets the original filename for this attachment
    ''' </summary>
    Public Property Filename() As String
        Get
            Return _filename
        End Get
        Set(ByVal value As String)
            _filename = value
        End Set
    End Property
    Private _mediaType As String
    ''' <summary>
    ''' Gets the attachment type: Bytes or String
    ''' </summary>
    Public Property MediaType() As String
        Get
            Return _mediaType
        End Get
        Set(ByVal value As String)
            _mediaType = value
        End Set
    End Property
    ''' <summary>
    ''' Gets the file for this attachment (as a new attachment)
    ''' </summary>
    Public ReadOnly Property File() As Attachment
        Get
            Return New Attachment(Stream, Filename, MediaType)
        End Get
    End Property
    ''' <summary>
    ''' Gets the length of this attachement data
    ''' </summary>
    Public ReadOnly Property Size() As Double
        Get
            Return Me.Stream.Length
        End Get
    End Property
    ''' <summary>
    ''' Construct a mail attachment form a byte array
    ''' </summary>
    ''' <param name="data">Bytes to attach as a file</param>
    ''' <param name="filename">Logical filename for attachment</param>
    Public Sub New(ByVal data() As Byte, ByVal filename As String)
        Me.Stream = New MemoryStream(data)
        Me.Filename = filename
        Me.MediaType = MediaTypeNames.Application.Octet
    End Sub
    ''' <summary>
    ''' Construct a mail attachment from a string
    ''' </summary>
    ''' <param name="data">String to attach as a file</param>
    ''' <param name="filename">Logical filename for attachment</param>
    Public Sub New(ByVal data As String, ByVal filename As String)
        Me.Stream = New MemoryStream(System.Text.Encoding.ASCII.GetBytes(data))
        Me.Filename = filename
        Me.MediaType = MediaTypeNames.Text.Html
    End Sub
End Class

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Student
India India
Hariharan leapt into the field of programming after being introduced to C in his second year at college. A fan of basketball and chess, the logical thought process behind programming and the concepts of linking real principles onto a concrete platform pushed him deep into this field. On finishing his bachelor's majoring in Electrical and Electronics engineering with Soft Computing, Numerical Analysis and Biomedical Engineering as minor, he did a six month stint at India's second largest IT company- Infosys Technologies. He left Infosys armed with strong concepts of SDL Cycles and process development, gained domain knowledge in Java and had explored Visual basic, C++, C# and kept his mind open for more. Currently working in a startup as the product designer, his arsenal of technologies has doubled to accommodate the challenges his job demands.
Off work, he enjoys learning new languages (non-programming) and is currently teaching himself German and Spanish. He also enjoys travelling around and exploring new ideas, places and relationships.

Currently attempting to extend his education to post graduation.

Comments and Discussions

 
GeneralYes that will do it. I also want to add a correction at this... Pin
Hariharan Arunachalam8-Mar-11 0:26
Hariharan Arunachalam8-Mar-11 0:26 
GeneralIs this correct? Dim timeout As Integer ... Pin
Kraeven8-Mar-11 0:10
Kraeven8-Mar-11 0:10 
GeneralHi, A question; can you tell me how to make this .NET 2.0 c... Pin
Kraeven7-Mar-11 23:12
Kraeven7-Mar-11 23:12 
GeneralThank you! I've got the complete implementation of a mailer ... Pin
Hariharan Arunachalam7-Mar-11 22:25
Hariharan Arunachalam7-Mar-11 22:25 
GeneralKeep up the good work! Knowledge needs to be shared to enli... Pin
Kraeven7-Mar-11 20:40
Kraeven7-Mar-11 20:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.