(a.k.a. When Simple Mail Transfer Protocol isn’t quite as simple as it sounds)
I wanted to build in a feature that sent an email from a button click in a Windows Form in VB.NET 2005. This is something I have seen asked about many times in VB and VB.NET Forums over the years. It turned out to be less easy than I thought it would be (nothing new there, then!)
The difficulty I found wasn’t with the creation of the mail message or the code to set up the addresses, headers, body, etc. This is all made very easy now with the Framework 2.0 Net.Mail class. The big problem was working out how to set up my PC to relay the emails out to the required addresses. The error messages didn’t offer me a huge amount of helpful information (and that’s being polite about it) :-{
I received plenty of messages telling me that the mail had failed to be relayed, but no useful pointers to where to start looking for the fault. A search of the Help files should have quickly resolved it, or so you would think. But in fact I found that I had to scratch around various forums, articles and, yes OK, there was some partial guidance on MSDN, but it was very much groping my way in the dark with a very dim and flickering torch.
In case you should find yourself frustrated by this seemingly simple developer task, here are the steps I eventually took in order to get the mail relay to function.
What I did (In Windows XP)
1. Checked that IIS is installed.
If you are not sure if you have it installed, one way of checking is to go to Control Panel - Administrative Tools and see if there is a folder named “Internet Information Services”.
2a. If there is such a folder, you will have IIS installed.
2b. If not, you can install it via the Control Panel
(i) Select “Add or Remove Programs”
(ii) click the Add/Remove Windows Components. Button.
(iii) Select Internet Information Services,
(iv) click on “Details” and ensure that “SMTP Service” is ticked.
(Alternatively you can confirm if IIS is installed simply by following that Control Panel - Add or Remove Programs - Add/Remove Windows Components route and checking for the elements that are currently installed)
3. Now that you have IIS and its SMTP facility installed, you need to check that the Relay Setting is enabled.
Relay Settings
- From the Start menu Select Control Panel – Administrative Tools – Internet Information Services .
- This will bring you to the IIS manager screen .
- LEFT Click on the + symbol next to the name of your local machine
- RIGHT click on “Default SMTP Virtual Server”
- Select “Properties” – then click the “General” tab
- In the IP Address combobox select “127.0.0.1”
- Now click the “Access” Tab
- Press the “button marked “Relay”
- Select the Radio Button which reads “All except the list below”. (The list box will most probably be empty anyway.)
- Make sure that the checkbox which reads “ Allow all computers which successfully authenticate to relay regardless of the list above” is checked.
- Select OK (in both of the dialog boxes) to save these settings, close the dialogs and return you to the IIS Manager screen.
(Optional Step 12) Take a deep breath and cross your fingers . Not many technical manuals include this important step, but I’ve often found it helps :-}
Creating and sending an email
To test that all is as it should be, you can use a Windows Form and add this code – changing any of the details such as email addresses, as necessary.
At the top of the form:
Imports System.Net.Mail
Inside the form’s code window:
Public Sub SendAnEmail(ByVal MsgFrom As String, ByVal MsgTo As String, ByVal MsgSubject As String, ByVal MsgBody As String)
Try
' Pass in the message information to a new MailMessage
Dim msg As New Net.Mail.MailMessage(MsgFrom, MsgTo, MsgSubject, MsgBody)
' Create an SmtpClient to send the e-mail
Dim mailClient As New SmtpClient("127.0.0.1") ' = local machine IP Address
' Use the Windows credentials of the current User
mailClient.UseDefaultCredentials = True
' Pass the message to the mail server
mailClient.Send(msg)
' Optional user reassurance:
MessageBox.Show(String.Format("Message Subject ' {0} ' successfully sent From {1} To {2}", MsgSubject, MsgFrom, MsgTo), "EMail", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
' Housekeeping
msg.Dispose()
Catch ex As FormatException
MessageBox.Show(ex.Message & " :Format Exception")
Catch ex As SmtpException
MessageBox.Show(ex.Message & " :SMTP Exception")
End Try
End Sub
Then all that remains to do is create some calling code . This example uses a button click to send data that I type into four textboxes with self-explanatory names: (You can replace them with literal strings of your own)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SendAnEmail(FromBox.Text, ToBox.Text, SubjectBox.Text, MsgBodyBox.Text)
End Sub
As it took me quite a lot of digging around to find this “easy” answer to what I thought was a very basic task for WinForms, I thought I’d share it via my blog.