How to send emails in .NET part 11: credentials

In the previous part in this mini-series we looked at how to handle exceptions. We’ll briefly look at authentication in this post.

Some SMTP servers require you to provide a username and password in order to send emails.

You can set the default network credentials as follows:

string smtpServer = "mail.blahblah.com";
SmtpClient client = new SmtpClient(smtpServer);
client.UseDefaultCredentials = true;

Another way to achieve the same is the following:

client.Credentials = CredentialCache.DefaultNetworkCredentials;

…where CredentialCache is found in the System.Net namespace.

You can also set the username and password manually as follows:

client.Credentials = new NetworkCredential("name", "password");

Read all posts related to emailing in .NET here.

How to send emails in .NET part 10: handling exceptions

In this mini series on emailing in .NET we saw how to compose and send emails.

There are many things that can go wrong when you send an email: the SMTP server is down, your credentials are invalid, the recipient is invalid etc. When sending an email in .NET you should always catch and handle any SmtpExceptions and SmtpFailedRecipientExceptions. Examples:

SmtpClient client = new SmtpClient(null);
try
{
	client.Send(mailMessage);
}
catch (InvalidOperationException invalid)
{
	Console.WriteLine("Server hostname is missing: " + invalid.Message);
}

InvalidOperationException is thrown in case the host is missing.

string smtpServer = "mail.blahblah.com";
SmtpClient client = new SmtpClient(smtpServer);
try
{
	client.Send(mailMessage);
}
catch (SmtpException smtpNotFound)
{
	Console.WriteLine("Server hostname is invalid: " + smtpNotFound.Message);
}

SmtpClient will try to contact mail.blahblah.com but fails of course. If you run this code then be patient as the default timeout of SmtpClient is 100 seconds, so you won’t see the exception message immediately.

In the above case SmtpException will have an inner exception of type WebException. smtpNotFound.Message like above will only show a generic message: “Failure sending mail”. If you want to dig deeper you’ll need to check if there’s any inner exception:

string smtpServer = "mail.blahblah.com";
SmtpClient client = new SmtpClient(smtpServer);
try
{
	client.Send(mailMessage);
}
catch (SmtpException smtpNotFound)
{
	Console.WriteLine("Server hostname is invalid: " + smtpNotFound.Message);
        if (smtpNotFound.InnerException != null)
	{
		Console.WriteLine(smtpNotFound.InnerException.Message);
	}
}

The inner exception message will be “Unable to connect to the remote server”.

SmtpException can also be thrown if the operation times out, but in that case there will be no inner exceptions:

SmtpClient client = new SmtpClient(smtpServer);
client.Timeout = 10;
try
{
	client.Send(mailMessage);
}
catch (SmtpException smtpNotFound)
{
	Console.WriteLine("Server hostname is invalid: " + smtpNotFound.Message);
}

We set the timeout to 10 seconds which is reached before SmtpClient determines that the SMTP server cannot be reached. Hence the exception message will say “The operation has timed out.”

SmtpException can also be thrown for a variety of other reasons like message transmission problems, so don’t forget to check the inner exception as well, it may contain a more detailed description of the problems.

There’s also an exception of type SmtpFailedRecipientException. If you work at GreatCompany Ltd. and your mail server is mail.greatcompany.com and you want to send an email to john@greatcompany.com then your mail server will be able to determine if the recipient exists and return an error if it doesn’t. If however, you’re sending an email to a recipient on another mail server then mail.greatcompany.com won’t of course see whether the recipient is valid or not. So you can only rely on this exception type if you’re sending an email within your network.

In this post we saw how to send an email asynchronously through SendAsync. The event arguments to the SendCompleted event handler includes a property called Error. If you send your email in this manner than the InvalidOperationException and SmtpException error caught will be set to this property so you can check the result.

Read all posts related to emailing in .NET here.

How to send emails in .NET part 9: sending emails

Up to now in this mini series we’ve looked at how to compose email messages. The next step is to actually send them to the recipient(s).

We saw that the easiest way to send a message is using the SmtpClient.Send method:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "This is the subject";
string plainTextBody = "This is a great message.";
MailMessage mailMessage = new MailMessage(from, to, subject, plainTextBody);
string smtpServer = "mail.company.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

The Send method is a “normal” synchronous method, i.e. it will block the code execution until the email has been sent.

In case you’d like to send the message asynchronously you have at least 2 options. If you have a .NET 4.5 project then you can use the awaitable version of Send, which is SendMailAsync. You don’t know what await-async means? Start here.

The updated code looks like this then:

public async Task SendMessageAsync()
{
	string from = "andras.nemes@company.com";
        string to = "john.smith@company.com";
        string subject = "This is the subject";
        string plainTextBody = "This is a great message.";
        MailMessage mailMessage = new MailMessage(from, to, subject, plainTextBody);
        string smtpServer = "mail.company.com";
        SmtpClient client = new SmtpClient(smtpServer);
	await client.SendMailAsync(mailMessage);
}

You’d then call the method as follows:

await SendMessageAsync();

Another option is to use the SendAsync method of SmtpClient and hook up to its SendCompleted event:

SmtpClient client = new SmtpClient(smtpServer);
client.SendCompleted += client_SendCompleted;
client.SendAsync(mailMessage, "Hello world");	

…where client_SendCompleted is an event handler:

void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
	Console.WriteLine("Cancelled? " + e.Cancelled);
	Console.WriteLine("Error? " + (e.Error == null));
	Console.WriteLine("User specified arg " + (e.UserState == null ? "none" : e.UserState.ToString()));
}

…which is called when the sending operation has completed. You can then read if the sending operation has been cancelled, if there are any exceptions and if there are any custom arguments in the UserState object. You can supply your own object here, any object, through the SendAsync method. In the above example I simply put “Hello world” as the custom argument which can be retrieved as e.UserState.ToString().

The sending can be cancelled by the SmtpClient.SendAsyncCancel() method which can be triggered if e.g. the user clicks a button if it takes too long to send the email.

In case your SMTP server supports SSL then make sure you take advantage of it and send the email in an encrypted form:

client.EnableSsl = true;

Read all posts related to emailing in .NET here.

How to send emails in .NET part 8: adding images to HTML contents

In this and this post we saw how to the build a HTML message and style it up. Let’s now see how to add images, such as a company logo or a photo.

The standard img tag is used to fulfil this need but in a special way. In standard HTML you can use the src attribute to refer to a file on the local drive or on another server, like http://mysite.com/images/hello.jpg. Pointing to a local file in an email is of course futile as you never know what’s on the recipient’s local machine. Referring to external files in HTML emails is problematic. They will be ignored by many email clients. At best the recipient will need to confirm that the images can be downloaded upon opening the email.

Instead the image will need to be added to the MailMessage object as a LinkedResource in an AlternateView. The LinkedResource must be assigned a unique content ID – unique among all linked resources in the message. You’ll need to refer to this content ID in the src attribute of the img tag in the HTML email body.

Consider the following example:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "Testing html body with image";
string htmlBody = @"
<html lang=""en"">	
	<body>
		<p>This is an image</p>
		<img src=""cid:WinLogo"" />
	</body>
</html>
";
AlternateView alternateViewHtml = AlternateView.CreateAlternateViewFromString(htmlBody, Encoding.UTF8, MediaTypeNames.Text.Html);
LinkedResource windowsLogo = new LinkedResource(@"c:\windows_logo.png", MediaTypeNames.Image.Jpeg);
windowsLogo.ContentId = "WinLogo";
alternateViewHtml.LinkedResources.Add(windowsLogo);
			
string plainTextVersionBody = "You should see a Windows logo here.";
AlternateView alternateViewText = AlternateView.CreateAlternateViewFromString(plainTextVersionBody, Encoding.UTF8, MediaTypeNames.Text.Plain);
			
MailMessage mailMessage = new MailMessage(from, to, subject, htmlBody);
mailMessage.AlternateViews.Add(alternateViewHtml);
mailMessage.AlternateViews.Add(alternateViewText);
string smtpServer = "mail.company.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

Note the following:

  • We create two alternate views: one HTML and one simple text. This is to ensure that the user will see at least a plain text version if the mail client cannot render HTML
  • The content ID of the LinkedResource is set to “WinLogo”
  • The same ID is referred to trough the src attribute om the image tag. Note the “cid:” bit within the contents of the src attribute.

The above code generates the following email in my Outlook client:

Simple HTML body in email with embedded picture

Read all posts related to emailing in .NET here.

How to send emails in .NET part 7: adding style to HTML contents

In this post we saw how to build a simple HTML email with no styling. It looked a bit bleak so we’ll “dress it up” a little.

You cannot simply add a reference to an external CSS file like you would on a normal HTML web page. External references are ignored in the email body as they can can contain malicious material and code.

You can place CSS code directly in the HTML code in the following ways:

  • Using the style tag within the head section
  • Using the style attribute on individual elements
  • Using old-style attributes, such as cellspacing, border, width etc. on individual elements

All of these should be familiar from general web UI programming. Here’s an example of an embedded style tag in the head section:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "Testing html body";
string htmlBody = @"
<html lang=""en"">
	<head>	
		<meta content=""text/html; charset=utf-8"" http-equiv=""Content-Type"">
		<title>
			Upcoming topics
		</title>
		<style type=""text/css"">
			HTML{background-color: #e8e8e8;}
			.courses-table{font-size: 12px; padding: 3px; border-collapse: collapse; border-spacing: 0;}
			.courses-table .description{color: #505050;}
			.courses-table td{border: 1px solid #D1D1D1; background-color: #F3F3F3; padding: 0 10px;}
			.courses-table th{border: 1px solid #424242; color: #FFFFFF;text-align: left; padding: 0 10px;}
			.green{background-color: #6B9852;}
		</style>
	</head>
	<body>
		<table class=""courses-table"">
			<thead>
				<tr>
					<th class=""green"">Topic</th>
					<th class=""green"">Est. # of posts</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td class=""description"">Using a Windows service in your project</td>
					<td>5</td>
				</tr>
				<tr>
					<td class=""description"">More RabbitMQ in .NET</td>
					<td>5</td>
				</tr>
			</tbody>
		</table>
	</body>
</html>
";
MailMessage mailMessage = new MailMessage(from, to, subject, htmlBody);
mailMessage.IsBodyHtml = true;
string smtpServer = "mail.company.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

The above message is rendered as follows in my MS outlook client:

Styled HTML body in email

It’s still not very corporate looking but now you at least know how to add styles to a HTML message in .NET.

Keep in mind that email clients are not as up-to-date with CSS code as modern web browsers, so not everything will work in an email.

Read all posts related to emailing in .NET here.

How to send emails in .NET part 6: HTML contents basics

In previous posts regarding emails – see the link below – we looked at how to send plain text emails. However, professional company emails, such as user sign-up confirmations, have almost exclusively HTML body formats for styling and layout.

Let’s start with the basics and send out a HTML-based email with no styling. You can freely add HTML tags to the body of the email and set the IsBodyHtml property as true:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "Testing html body";
string htmlBody = @"
<html lang=""en"">
	<head>	
		<meta content=""text/html; charset=utf-8"" http-equiv=""Content-Type"">
		<title>
			Upcoming topics
		</title>
	</head>
	<body>
		<table>
			<thead>
				<tr>
					<th>Topic</th>
					<th>Est. # of posts</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					  <td>Using a Windows service in your project</td>
					  <td>5</td>
				  </tr>
				  <tr>
					  <td>More RabbitMQ in .NET</td>
					  <td>5</td>
				  </tr>
			</tbody>
		</table>
	</body>
</html>
";
MailMessage mailMessage = new MailMessage(from, to, subject, htmlBody);
mailMessage.IsBodyHtml = true;
string smtpServer = "mail.company.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

The email client will then render the HTML as best as it can. You cannot however just send any HTML that you may be used to from web programming. Most email clients will ignore external files, like JS, images, CSS files etc. Also, inline JavaScript code won’t be executed.

The above message was rendered in my MS Outlook client as follows:

Simple HTML body in email

Read all posts related to emailing in .NET here.

How to send emails in .NET part 5: attachments

Adding an attachment to a MailMessage object can be as simple as inserting an Attachment object to the Attachments collection:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "Testing email attachment";
string plainTextBody = "This is a great message.";
MailMessage mailMessage = new MailMessage(from, to, subject, plainTextBody);

mailMessage.Attachments.Add(new Attachment(@"C:\logfile.txt"));

string smtpServer = "mail.apicasystem.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

You can also specify the MIME type – Multipurpose Internet Mail Extensions – using the MediaTypeNames enumeration. E.g. you can add an attachment as a Stream in the following way:

Stream attachmentStream = new FileStream(@"C:\logfile.txt", FileMode.Open, FileAccess.Read);
mailMessage.Attachments.Add(new Attachment(attachmentStream, "recent_log.txt", MediaTypeNames.Text.Plain));

Note that you can specify a different file name in the Attachment constructor. It can differ from the name of the original source. You can even change its extension if you want, such as “myfile.html”. If you’re not sure of the MIME type you can use MediaTypeNames.Application.Octet which indicates a binary file.

Read all posts related to emailing in .NET here.

How to send emails in .NET part 4: other features of the MailMessage object

We looked at the MailMessage object in various posts here, here and here. Let’s look at some less frequently used features of this object.

Notification options

You can instruct the SMTP server to send a notification to the From address depending on the status of the message. The available statuses are stored in the DeliveryNotificationOptions enumeration:

  • Never: don’t send any notification regardless of what happens with the message
  • Delay: send notification in case of a delay in the delivery
  • None: the default value, let the SMPT server decide whether to send any notification
  • OnFailure: send notification if failed
  • OnSuccess: send notification if delivery succeeded

You can also chain the options as follows:

string from = "andras.nemes@company.com";
string to = "john.smith@company.com";
string subject = "Testing notification options-";
string plainTextBody = "This is a great message.";
MailMessage mailMessage = new MailMessage(from, to, subject, plainTextBody);
mailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess | DeliveryNotificationOptions.OnFailure;

Note, however, that the SMTP server may refuse to send any notification to the From address depending on its settings. So setting this property is more of a wish, unless you directly control the email server settings.

Different ReplyTo

You can change the ReplyTo address(es) of the email using the ReplyToList object of type MailMessageCollection. The effect will be that when the recipient presses Reply in her email client the To field will be populated with this modified ReplyTo address:

mailMessage.ReplyToList.Add(new MailAddress("info@company.com"));

So in case you’d like the recipient send the response to an address different from the “From” email then use this option.

Priority

Would you like to send you email with an exclamation mark so that the recipient knows that it is super-urgent? Use the Priority enumeration: High, Low or Normal, which is the default:

mailMessage.Priority = MailPriority.High;

Read all posts related to emailing in .NET here.

How to send emails in .NET part 3: multiple recipients, CC and BCC

In this post we looked at how to send a plain text email. Let’s see how we can refine the recipient list of the email message.

The MailMessage object has a To property of type MailAddressCollection. You can add MailAddress objects to this collection if you’d like to send the message to multiple recipients:

MailMessage mailMessage = new MailMessage();
mailMessage.To.Add(new MailAddress("xxx.yyy@yyy.com"));
mailMessage.To.Add(new MailAddress("zzz.nnn@fff.com"));
mailMessage.To.Add(new MailAddress("ttt.ddd@jjj.com"));
mailMessage.Subject = "subject";
mailMessage.Body = "body";

Similarly, the MailMessage object has a CC and Bcc property of type MailAddressCollection to hold the carbon copy and blind carbon copy recipients of the message. You can add MailAddress objects to those properties the same way as above:

mailMessage.CC.Add(new MailAddress("ggg@hhh.com"));
mailMessage.Bcc.Add(new MailAddress("lll@kkk.com"));

You can also specify a list of email addresses in a comma-separated string instead of adding MailAddress objects one by one:

mailMessage.To.Add("x@y.com,z@n.com,elvis@presley.com");

Read all posts related to emailing in .NET here.

How to send emails in .NET part 2: the MailAddress object

In the previous post on this topic we saw how to send a plain text email with the MailMessage and SmtpClient objects.

You can refine the From and To fields of the message using the MailAddress object. You can specify the email address, a display name and an encoding. Specifying an encoding is seldom necessary.

So if you’d like to joke with your colleagues then this is one option:

MailAddress from = new MailAddress("andras.nemes@company.com", "Your boss");
MailAddress to = new MailAddress("john.smith@company.com");
string subject = "You are fired.";
string plainTextBody = "See you in hell.";
MailMessage mailMessage = new MailMessage(from, to);
mailMessage.Subject = subject;
mailMessage.Body = plainTextBody;

string smtpServer = "mail.company.com";
SmtpClient client = new SmtpClient(smtpServer);
client.Send(mailMessage);

The recipient will see an email similar to the following:

Changing display name of sender

Of course they will eventually see the actual email address of the sender but they might get scared at first.

Read all posts related to emailing in .NET here.

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: