Link to home
Start Free TrialLog in
Avatar of ICantSee
ICantSeeFlag for United States of America

asked on

emails not sending from web app

The emails are not sending. This code was given to me today by an expert and I am unsure how to adapt the email portion ( Private Sub SendEmail(toAddress As String)) to my network.

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Public Class _Default
    Inherits Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        If (IsPostBack = False) Then
            Dim con As SqlConnection = Nothing
            Dim command As SqlCommand = Nothing
            Dim adapter As SqlDataAdapter = Nothing
            Dim table As DataTable = Nothing
            Try
                con = New SqlConnection(ConfigurationManager.ConnectionStrings("EETest").ConnectionString)
                con.Open()
                command = New SqlCommand("SELECT UserName FROM [Users]", con)
                adapter = New SqlDataAdapter(command)
                table = New DataTable()
                adapter.Fill(table)
                ddlName.DataSource = table
                Dim rowSelect As DataRow = table.NewRow
                rowSelect(0) = "Please Select"
                table.Rows.InsertAt(rowSelect, 0)
                ddlName.DataTextField = "UserName"
                ddlName.DataValueField = "UserName"
                ddlName.DataBind()
            Catch ex As Exception
                '-=- error handling
            Finally
                If (IsNothing(con) = False) Then
                    If (con.State = ConnectionState.Open) Then con.Close()
                    con.Dispose()
                End If
                If (IsNothing(command) = False) Then command.Dispose()
                If (IsNothing(adapter) = False) Then adapter.Dispose()
            End Try
        End If
    End Sub

    Protected Sub ddlName_SelectedIndexChanged(sender As Object, e As EventArgs)
        Dim con As SqlConnection = Nothing
        Dim command As SqlCommand = Nothing
        Dim adapter As SqlDataAdapter = Nothing
        Dim table As DataTable = Nothing
        Try
            If (ddlName.SelectedItem.Text = "Please Select") Then
                lblEmailAddress.Text = ""
                txtDescription.Visible = False
                btnSubmit.Visible = False
                Exit Sub
            End If
            con = New SqlConnection(ConfigurationManager.ConnectionStrings("EETest").ConnectionString)
            con.Open()
            command = New SqlCommand("SELECT EmailAddress FROM [Users] WHERE UserName = @UserName", con)
            command.Parameters.AddWithValue("@UserName", ddlName.SelectedItem.Text)
            adapter = New SqlDataAdapter(command)
            table = New DataTable
            adapter.Fill(table)
            lblEmailAddress.Text = Convert.ToString(table.Rows(0)("EmailAddress"))
            txtDescription.Visible = True
            btnSubmit.Visible = True
        Catch
            '-=- error handling
        Finally
            If (IsNothing(con) = False) Then
                If (con.State = ConnectionState.Open) Then con.Close()
                con.Dispose()
            End If
            If (IsNothing(command) = False) Then command.Dispose()
            If (IsNothing(adapter) = False) Then adapter.Dispose()
        End Try
    End Sub

    Protected Sub btnSubmit_Click(sender As Object, e As EventArgs)
        Dim con As SqlConnection = Nothing
        Dim command As SqlCommand = Nothing
        Try
            con = New SqlConnection(ConfigurationManager.ConnectionStrings("EETest").ConnectionString)
            con.Open()
            command = New SqlCommand("INSERT INTO [ScrapDB].[dbo].[Tickets] ([DateLogged], [UserName], [Description]) VALUES (@DateLogged, @UserName, @Description)", con)
            command.Parameters.AddWithValue("@DateLogged", DateTime.Now)
            command.Parameters.AddWithValue("@UserName", ddlName.SelectedItem.Text)
            command.Parameters.AddWithValue("@Description", txtDescription.Text)
            command.ExecuteNonQuery()
            txtDescription.Visible = False
            btnSubmit.Visible = False
            lblThankYou.Visible = True
            SendEmail(lblEmailAddress.Text)
            SendEmail(ConfigurationManager.AppSettings("SupportEmailAddress"))
        Catch
            '-=- error handling
        Finally
            If (IsNothing(con) = False) Then
                If (con.State = ConnectionState.Open) Then con.Close()
                con.Dispose()
            End If
            If (IsNothing(command) = False) Then command.Dispose()
        End Try
    End Sub

    Private Sub SendEmail(toAddress As String)
        Try
            Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("FromAddress"), toAddress)
            msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
            msg.Body = txtDescription.Text
            Dim client As New System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings("SMTPHostServer"), Integer.Parse(ConfigurationManager.AppSettings("SMTPHostPort")))
            client.UseDefaultCredentials = True
            client.Send(msg)
        Catch ex As Exception
            '-=- error handling
        End Try
    End Sub
End Class

Open in new window

Avatar of ICantSee
ICantSee
Flag of United States of America image

ASKER

I should mention that my web.config file has the email settings in it:
    <system.net>
    <mailSettings>
      <smtp from="emailaddress@mydomain.org">
       <network host="x.x.x.x." password="******" userName="*****"  />
      </smtp>
    </mailSettings>
  </system.net>

Open in new window

Avatar of UnifiedIS
UnifiedIS

Did you update the config file with the values for your mail server?

The code in the SendEmail routine is set to ignore errors.  You may want to modify the 'catch' block so it is handled instead of ignored. I would at least output the exception to the console window for debugging in the dev environment.


 Private Sub SendEmail(toAddress As String)
        Try
            Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("FromAddress"), toAddress)
            msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
            msg.Body = txtDescription.Text
            Dim client As New System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings("SMTPHostServer"), Integer.Parse(ConfigurationManager.AppSettings("SMTPHostPort")))
            client.UseDefaultCredentials = True
            client.Send(msg)
        Catch ex As Exception
            '-=- error handling
        End Try
    End Sub
the from address will be the sender of the email
The host is your mail server, in the config x.x.x.x is to be replaced by the IP address.  Name of the server also works, i.e. "mail.mycompany.com" or 172.10.1.200

If your mail server requires authentication, you need a user name and password in those fields in the config
puzzling... I have those entries in the web.config file.

This is what I tried:

 btnSubmit.Visible = False
            lblThankYou.Visible = True
            SendEmail(lblEmailAddress.Text)
            SendEmail(ConfigurationManager.AppSettings("kevin@keystoneblind.org"))
        Catch
            '-=- error handling
        Finally
            If (IsNothing(con) = False) Then
                If (con.State = ConnectionState.Open) Then con.Close()
                con.Dispose()
            End If
            If (IsNothing(command) = False) Then command.Dispose()
        End Try
    End Sub

    Private Sub SendEmail(toAddress As String)
        Try
            Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("kba_forms@keystoneblind.local"), toAddress)
            msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
            msg.Body = txtDescription.Text
            Dim client As New System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings("MailServerIP"), Integer.Parse(ConfigurationManager.AppSettings("CorrectPortNumber")))
            client.UseDefaultCredentials = True
            client.Send(msg)
        Catch ex As Exception
            '-=- error handling
        End Try

Open in new window


The correct ip address, username and password are entered in the web.config file.

Then I tried:
    Private Sub SendEmail(toAddress As String)
        Try
            Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("kba_forms@keystoneblind.org"), toAddress)
            msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
            msg.Body = txtDescription.Text

            Dim client As New System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings("EmailServerIP"), Integer.Parse(ConfigurationManager.AppSettings("CorrectPortNumber")))
            client.UseDefaultCredentials = False
            client.Credentials = New System.Net.NetworkCredential("Correct username", "Correct password")
            client.Send(msg)
        Catch ex As Exception
            '-=- error handling
        End Try

Open in new window

Try putting something in the catch block to see if an exception is being thrown (check the output window)
Catch ex As Exception
       console.writeline(ex.tostring)
I added this, but nothing happened..

            client.Send(msg)
        Catch ex As Exception
            Console.WriteLine("failed to send email with the following error:")
            Console.WriteLine(ex.Message)
        End Try

Open in new window

Have you stepped through the code in debug mode to make sure that the SendEmail method is being called?

If it is, check the properties of msg to make sure you have the to and, from addresses
All email settings are stored in AppSettings
Change the email server settings to use that, and it will work.
Avatar of kaufmed
All email settings are stored in AppSettings
Eh, I wouldn't suggest doing that, but I do agree that you've set up the code to pull from the <appSettings> section of your configuration file. Why do this? You've already configured the <mailSettings> section, so why not let that section do its thing? I would modify your code to:

Private Sub SendEmail(toAddress As String)
    Try
        Dim client As New System.Net.Mail.SmtpClient()  ' Pulls its info from the <mailSettings> section
        Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("FromAddress"), toAddress)

        msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
        msg.Body = txtDescription.Text

        client.Send(msg)
    Catch ex As Exception
        '-=- error handling
    End Try
End Sub

Open in new window


You might want to tweak either your config file or the code just a bit:  You've already entered the "from" in the <mailSettings> section, so adding it to the <appSettings> section would seem redundant, but it might be quicker to do so.
I rewrote part of the sendemail using the mailaddress and mailaddresscollection objects for the to and from. I also recommend hardcoding your smtp server (and port if necessary) until you can get the email to send.  Determining best ways to get that is of secondary importance.

Dim msg As New System.Net.Mail.MailMessage()
Dim maddColl As New System.Net.Mail.MailAddressCollection()
maddColl = msg.To
maddColl.add(toAddress)
msg.From = new System.Net.Mail.MailAddress("kba_forms@keystoneblind.org")
msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
msg.Body = txtDescription.Text
Dim client As New System.Net.Mail.SmtpClient(HardCodeYourMailServerUntilItWorks, HardCodeYourPortUntilItWorks)

'What you have seems reasonable but I don't have to authenticate to send mail
            client.UseDefaultCredentials = False
           client.Credentials = New System.Net.NetworkCredential("Correct username", "Correct password")
client.Send(msg)
No luck. I replaced the SendMail with the new code..

Protected Sub btnSubmit_Click(sender As Object, e As EventArgs)
        Dim con As SqlConnection = Nothing
        Dim command As SqlCommand = Nothing


        Try
            con = New SqlConnection(ConfigurationManager.ConnectionStrings("I.T. DataCS").ConnectionString)
            con.Open()
            command = New SqlCommand("INSERT INTO [I.T. Data].[dbo].[Tickets] ([TicketDate], [FullName], [IssueDescription]) VALUES (@DateLogged, @UserName, @Description)", con)
            command.Parameters.AddWithValue("@DateLogged", DateTime.Now)
            command.Parameters.AddWithValue("@UserName", ddlName.SelectedItem.Text)
            command.Parameters.AddWithValue("@Description", txtDescription.Text)
            command.ExecuteNonQuery()
            DescribeIssueLabel.Visible = False
            txtDescription.Visible = False
            btnSubmit.Visible = False
            lblThankYou.Visible = True
            SendEmail(lblEmailAddress.Text)
            SendEmail(ConfigurationManager.AppSettings("kevin@keystoneblind.org"))
        Catch ep As Exception
            Console.WriteLine("failed to send email with the following error:")
            Console.WriteLine(ep.Message)
        Finally
            If (IsNothing(con) = False) Then
                If (con.State = ConnectionState.Open) Then con.Close()
                con.Dispose()
            End If
            If (IsNothing(command) = False) Then command.Dispose()
        End Try
    End Sub

Private Sub SendEmail(toAddress As String)
        Try
            Dim client As New System.Net.Mail.SmtpClient()  ' Pulls its info from the <mailSettings> section
            Dim msg As New System.Net.Mail.MailMessage(ConfigurationManager.AppSettings("kba_forms@keystoneblind.local"), toAddress)

            msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
            msg.Body = txtDescription.Text

            client.Send(msg)
        Catch ex As Exception
            '-=- error handling
        End Try
    End Sub
End Class

Open in new window

This worked, but I don't understand why. ...

Expert Comment

UnifiedIS2014-07-03 at 03:49:22ID: 40174262


I rewrote part of the sendemail using the mailaddress and mailaddresscollection objects for the to and from. I also recommend hardcoding your smtp server (and port if necessary) until you can get the email to send.  Determining best ways to get that is of secondary importance.

 Dim msg As New System.Net.Mail.MailMessage()
 Dim maddColl As New System.Net.Mail.MailAddressCollection()
 maddColl = msg.To
 maddColl.add(toAddress)
 msg.From = new System.Net.Mail.MailAddress("kba_forms@keystoneblind.org")
 msg.Subject = "Ticket Logged by " & ddlName.SelectedItem.Text
 msg.Body = txtDescription.Text
 Dim client As New System.Net.Mail.SmtpClient(HardCodeYourMailServerUntilItWorks, HardCodeYourPortUntilItWorks)

 'What you have seems reasonable but I don't have to authenticate to send mail
             client.UseDefaultCredentials = False
            client.Credentials = New System.Net.NetworkCredential("Correct username", "Correct password")
 client.Send(msg)
Can you telnet to the SMTP server?

Either use putty and telnet to the port, or you can add a telnet client by going to add remove programs and adding feature "Telnet Client" then from a command prompt type "telnet <servername> <portnumber>"

Here is a more detailed explanation
http://technet.microsoft.com/en-us/library/aa995718(v=exchg.65).aspx
how do I add the I.T. staff email addresses to it?
I know... pressing my luck a little. But you seem to have the knowledge that I am looking for.

How would I add the data from other controls to the email if I added them on the page?

Also, I have built several apps using "send async" is that poor practice? Is your way better?

Dim myMessage As MailMessage = New MailMessage()
        myMessage.Subject = "Benefit Time Request"
        myMessage.Body = mailBody


        myMessage.IsBodyHtml = True
        myMessage.Priority = MailPriority.High
        myMessage.To.Add(New MailAddress("kevin@keystoneblind.org"))



        Dim mySmtpClient As SmtpClient = New SmtpClient()
        mySmtpClient.Credentials = New System.Net.NetworkCredential("CorrectUserId", "CorrectPassword")
        'mySmtpClient.Send(myMessage)

        Dim smtpClient As New SmtpClient()
        Dim userState As Object = myMessage

        'Attach event handler for async callback
        AddHandler smtpClient.SendCompleted, AddressOf SmtpClient_OnCompleted


        'Send the email asynchronously
        smtpClient.SendAsync(myMessage, userState)

    End Sub
    ''' <summary>
    ''' Event handler for processing completion information after asynchronous email sent.
    ''' </summary>
    Public Sub SmtpClient_OnCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)

        'Get UserState as MailMessage instance from SendMail()
        Dim mailMessage As MailMessage = CType(e.UserState, MailMessage)

        If (e.Cancelled) Then
            FeedBackLabel.Text = "Sending of the form was cancelled. Address=" '+ mailMessage.To(0).Address
        End If

        If Not (e.Error Is Nothing) Then
            FeedBackLabel.Text = "Error occured. Please contact KBA's technical support at 724.347.5501 ext 252"
        Else
            Response.Redirect("~/benefittime/Thankyou.aspx")
            mailMessage.Dispose()
        End If

Open in new window


Thank you for all of the responses. HUGE help.
With the MailAddressCollection, you can easily add multiple "to" addresses.

You could pass a comma-separated string and then use a split function and add each one to the the maddColl.
I prefer to use an arraylist as the "to" parameter and then I just loop through and add each value
For x As Integer = 0 To ToArrayList.Count - 1
            maddColl.Add(ToArrayList(x))
Next
Im sorry, its still greek to me. All I'm really doing is using your code. I don't understand it yet.

would I just add more maddColl.add(toAddress) with the needed addresses and then use

For x As Integer = 0 To ToArrayList.Count - 1
             maddColl.Add(ToArrayList(x))
 Next

just before End Sub ?
ASKER CERTIFIED SOLUTION
Avatar of UnifiedIS
UnifiedIS

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry for the slow response. I was out for the long weekend.
Awesome... above and beyond .. THANK YOU