What’s new in System.Net.Mail


What’s new in System.Net.Mail


We’ve made a number of enhancements to our SMTP support for .NET 4.0, mostly in the area of Unicode support and increased standards compliance, which is an important aspect in ensuring that legitimate emails do not get flagged as spam, as well as a few other useful features.  In this post I’ll go over these enhancements and what they mean to you as a developer.


Decreased likelihood of being accidentally flagged as spam


Many spammers don’t bother to follow the SMTP protocol correctly in sending their spam, so standards violations tend to be a major factor in calculating spam scores.  In .NET 4.0, we’ve made some significant improvements in how we encode headers and fold long lines of text in order to better comply with the SMTP protocol to reduce the likelihood that your legitimate emails will accidentally be caught by an overzealous spam filter.  You don’t need to change a thing in your code to take advantage of this since it’s all internal to System.Net.Mail.


Increased Unicode support


You can now include Unicode in your custom headers thanks to a new property to the MailMessage class called HeadersEncoding, which allows you to specify what Unicode encoding that custom headers are using so that they can be sent correctly (the default is UTF-8).  HeadersEncoding only affects custom headers that you add; the subject, body, and email address display names can have different encodings that are controlled by other properties in the MailMessage and MailAddress classes.


Clarification on setting header values


While MailMessage allows you direct access to the headers collection some headers being malformed could cause the email message to become corrupted.  The following is a list of headers that you should not set via the headers collection; any values you set for these headers will be silently discarded or overwritten when the message is sent (use the appropriate properties of MailMessage to control these headers):


Bcc, Cc, Content-ID, Content-Location, Content-Transfer-Encoding, Content-Type, Date, From, Importance, MIME-Version, Priority, Reply-To, Sender, Subject, To, X-Priority


Note: if you do not specify an X-Sender header, we will create one for you however we will not overwrite an X-Sender that you set. 


Multiple Reply-To addresses with the new property ReplyToList


We’ve added another new property to MailMessage called ReplyToList that allows you to add multiple Reply-To addresses to an email.  The ReplyTo property has been obsoleted.


Content Disposition time zones


We’ve received some feedback on how ContentDisposition does not allow you to specify time zones in the character formats dictated by RFC 822, such as “GMT” or “PST.”  This functionality was actually obsolete by RFC 2822, which replaces RFC 822, and dictates that an email time should always contain the offset for a timezone (e.g. “-0800” or “+0000”).  However, we will now accept RFC 822 time zone formats and convert them to their semantically equivalent offsets.  Whenever we are unable to determine the correct semantically equivalent offset, it is converted to “-0000” meaning that the time zone is unknown.  This affects strings passed to the constructor or Parameters collection of ContentDisposition.


Mail Address formats


We’ve improved our ability to parse email address strings in the MailAddress class.  Display names that contain Unicode cases and quoted local parts in the address will now be accepted correctly in most circumstances.  If an address does contain an invalid character, the exception message will inform you of what character was invalid.  Remember, you should format your email addresses as “displayname” <local@domain>. 


Authentication


Some legacy clients do not advertise their AUTH mechanisms correctly.  Normally, in the EHLO reply you would expect to see something like AUTH LOGIN NTLM advertising that this server supports LOGIN and NTLM authentication.  Some legacy servers will instead reply with AUTH=LOGIN NTLM which is a violation of the RFC, however we have added support to SmtpClient for these legacy servers so authentication will work correctly should you encounter one.


We hope that you find this new and improved functionality useful for your applications and, as always, feel free to drop us a line if you have any feedback on these features or anything else you would like to see!

Comments (12)

  1. Jack Bond says:

    "In .NET 4.0, we’ve made some significant improvements in how we encode headers and fold long lines of text in order to better comply with the SMTP protocol to reduce the likelihood that your legitimate emails will accidentally be caught by an overzealous spam filter."

    Great stuff, unless of course the spammers are using System.Net.Mail.

  2. jetucker says:

    True, spammers could potentially benefit from our improvements like any other user of System.Net.Mail, but this is unlikely to add to the amount of spam you receive for the following reasons:

    First, spam filters typically rely a Bayesian analysis of the content as the primary calculation for the spam score.  Spam emails will still have a higher spam score regardless of standards compliance.

    Second, since spammers rely on sending huge numbers of emails, adding custom headers increase the time necessary to send each email.  If you’re sending 20 million emails per day (approximately 231 mails per second) then even a .1% increase in the time to send each email means 21,000 fewer emails per day.  Since custom headers would add no value to spam, it’s unlikely to be a significant factor for preventing it.

  3. Chris Wright says:

    Sorry I accidentally posted this on the wrong page before, I meant to post it here. Here is the post again but this time on the correct page :)

    "I hope the SmtpClient will actually send the QUIT command when it has finished sending an email (or perhaps you could add a Close method or something) in this release…

    Every other SMTP client/server in the world that I have seen does this, it seems odd that the .NET one does not send it as it is such a simple thing to do."

  4. Aaron Oneal [MSFT] says:

    Chris, you won’t see that update in the Beta, but we have plans to address it before release.

  5. Chris Wright says:

    Ah right, that would be nice to see :)

    Thanks for the response

    Chris

  6. Phil says:

    Seriously???  What about VS2008 or VS2005 users???  This problem has been around for years, since 2.0 pre SP1.  Now you’re essentially forcing an update to VS 2010 to use .net 4, which fixes problems in system.net.mail that shouldn’t have been there in the first place.  Lovely.  That’s what RFC’s are for, when will you learn Microsoft?

    Yeah you’ve made enhancements, if you want to define enhancements as following the rules the rest of us have been for years.  Good job. /sarcasm

  7. Aaron Oneal [MSFT] says:

    Some RFCs are open to interpretation, some are non-specific in particular areas, and some go through multiple revisions. While we do our best to ensure every release meets a high quality bar, we do continue to improve areas over time. Periodic release snapshots with these improvements are part of the natural process of software development.

    Keep in mind too that while VS and .NET are updated in sync so that developer tools can leverage the latest platform updates, .NET 4 is a runtime which can be installed and developed for separately from VS.

  8. Lane Mohler says:

    This is exciting.  

    Are you also going to support folding as per RFC 5322 section 2.2.3?  

    Right now if you have an even moderately long subject line, it gets encoded as a single word by the encoder.  This breaks on Exchange which has a default maximum word length of 255.  

    Considering that some very common languages (like Thai) are above code point 1920, they use 3 bytes in UTF-8.  So that gives us some fairly short subjects.

    Thanks for the info!

  9. Aaron Oneal [MSFT] says:

    This form of folding by the encoder should now be supported.

  10. Ami Schreiber says:

    I have been working within the System.Net.Mail and System.Net.Mime namespaces pretty extensively over the last few months and like many other developers I find it severely lacking in certain aspects.

    The functionality that I am specifically referring to are the ability to load a MailMessage from a file on the file system and save a MailMessage object to the file system. I found examples that demonstrate how to save a MailMessage object but they all require the use of reflection. Loading a file from the file system or a filestream is totally unsupported and it would be VERY, VERY, VERY useful. Giving the MailMessage object the ability to parse complex files containing nested MimeParts that may or may not be encrypted and/or signed would be a wonderful addition to the .NET framework.

  11. Chris Wright says:

    I commented on this bog post last year asking about if the SmtpClient in .NET 4.0 would send the QUIT command when it is done sending a mail message and you said that in the final release of .NET 4.0 this should be sorted. I tested it the other day though and it looks like it still does not send QUIT… :(

  12. Aaron Oneal [MSFT] says:

    QUIT should be sent when Dispose is called. Can you confirm whether you called Dispose?