user: psw:
| lost password
ASP.NET 3.5 For Dummies :: Forums
Home » Stuff » A System.Net.Mail.MailMessage Mystery Solved Messages in this topic - RSS
2/6/2008 4:10:57 PM
Ken Cox
Posts 170
A System.Net.Mail.MailMessage Mystery Solved

One of the weirdest experiences in programming is when code that used to work suddenly starts acting up. Sure, something changed, but what and where.

I was testing the code in ASP.NET 3.5 For Dummies that sends an email message whenever a Web application encounters an unhandled exception. I'm sure the code (shown below) worked fine when I was writing the chapter. Suddenly, at the last minute (of course) this line:

Dim mailmsg As New System.Net.Mail.MailMessage

Threw a System.FormatException exception:

"The specified string is not in the form required for an e-mail address."

According to IntelliSense, it's perfectly legal to create a MailMessage object without passing anything to the constructor. It made absolutely no sense that I couldn't initialize an empty instance of the MailMessage class this way. Unable to figure it out late at night and under deadline pressure, I substituted an overload constructor in the book's code that takes two MailAddress objects. Although unhappy with the code, at least it didn't throw an exception at the poor reader.

The next day, with the panic over (the book was out of my hands), I had to investigate why code that worked before (granted in the ASP.NET 3.5 beta timeframe) was failing on me.

Although I had checked the online documentation for the MailMessage Class, I decided to look again more calmly. Suddenly, I came upon something in the default constructor for MailMessage. There's a little note in the Remarks:

"From is set to the value in the network element for mailSettings<smtp> Element (Network Settings), if it exists."

What could that mean? It sounded like the default constructor fetched the "From" email address from somewhere else. I searched for smtp in the web.config file and discovered this (as it turns out, broken) section:

<system.net>
<mailSettings>
<smtp from="KenCox.ca">
<network host="mail.kencox.ca" password="!youcantguessit!" userName="themailaccount@kencox.ca"/>
</smtp>
</mailSettings>
</system.net>

Okay, so I had started configuring this as part of the ASP.NET site's Login and Membership functions. It looked like the MailMessage constructor was picking up from="KenCox.ca" . I was getting closer but still stumped. As a test, I played with the From address and realized that it was supposed to be an email address with an @ symbol in it! No wonder my forehead is flattening out... it's all the slapping it gets during those DOH moments. <grin>

When I corrected the email address, the setting section looked like this:

<system.net>
<mailSettings>
<smtp from="goldie@KenCox.ca">
<network host="mail.kencox.ca" password="!youcantguessit!" userName="themailaccount@kencox.ca/>
</smtp>
</mailSettings>
</system.net>

The moral of the story is that if you get a weird error using System.Net.Mail, look in the web.config file and either fix the <mailSettings> and <smtp> stuff or comment it all out. Removing the section prevents MailMessage from picking up values that you might not know about.

While I'm not a class designer, I do find this odd. I would have preferred a parameter that indicates whether the constructor should look into the <smtp> section for its details.

Here's the code (for the global.asax file) to send someone an email message whenever an ASP.NET 3.5 Web application encounters an unhandled exception.

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
Try
Dim sb As New StringBuilder
Dim mailmsg As New System.Net.Mail.MailMessage
' Create "from" address:
Dim mailaddr As New System.Net.Mail.MailAddress _
("goldie@kencox.ca", "Goldie")
Dim mailer As New System.Net.Mail.SmtpClient()
' Create credentials of for the mail sender:
Dim creds As New System.Net.NetworkCredential _
("goldie@kencox.ca", "doggypassword")
Dim objErr As Exception

' Get original error into an error object
objErr = Server.GetLastError().GetBaseException()
Server.ClearError()
' Create the text for the body of the message
sb.AppendLine("<b>Source:</b>" & Request.RawUrl)
sb.AppendLine("<br><b>Browser:</b>" & Request.UserAgent)
sb.AppendLine("<hr><br><b>Error in: </b>" & Request.Url.ToString)
sb.AppendLine("<br><b>Error Message: </b>" & objErr.Message.ToString())
sb.AppendLine("<br><b>Stack Trace: </b><br>" & objErr.StackTrace.ToString())

' Create the email message
mailmsg.IsBodyHtml = True
mailmsg.Subject = "Error from Web site"
mailmsg.To.Add("testuser@gmail.com")
mailmsg.Body = sb.ToString()
mailmsg.From = mailaddr
mailer.Host = "mail.kencox.ca"
mailer.UseDefaultCredentials = False
mailer.Credentials = creds
mailer.Send(mailmsg)
Catch exc As Exception
' Do nothing about any other error
Finally
' Send them to the Oops page no matter what
Response.Redirect("~/oops.htm")
End Try
End Sub
pages: 1
the topic is closed |

Home » Stuff » A System.Net.Mail.MailMessage Mystery Solved