Send SMTP email using System.Net.Mail via Exchange Online (Office 365)

C#Exchange ServerOffice365Sendmailsystem.net.mail

C# Problem Overview


We are testing the new Office 365 beta, and i have a mail account on the Exchange Online service. Now I'm trying to connect a LOB application that can send smtp emails from my test account.

However the Exchange 365 platform requires TLS encryption on port 587, and there is a 'feature' of System.Net.Mail that does not permit Implicit SSL encryption.

Has anyone managed to get C# sending mails via this platform?

I have the following basic code that should send the mail - any advice would be appreciated.

SmtpClient server = new SmtpClient("ServerAddress");
server.Port = 587;
server.EnableSsl = true;
server.Credentials = new System.Net.NetworkCredential("[email protected]", "password");
server.Timeout = 5000;
server.UseDefaultCredentials = false;

MailMessage mail = new MailMessage();
mail.From = new MailAddress("recipent@anyaddress");
mail.To.Add("[email protected]");
mail.Subject = "test out message sending";
mail.Body = "this is my message body";
mail.IsBodyHtml = true;

server.Send(mail);

C# Solutions


Solution 1 - C#

Fixed a few typos in the working code above:

MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress("[email protected]", "SomeOne"));
msg.From = new MailAddress("[email protected]", "You");
msg.Subject = "This is a Test Mail";
msg.Body = "This is a test message using Exchange OnLine";
msg.IsBodyHtml = true;

SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("your user name", "your password");
client.Port = 587; // You can use Port 25 if 587 is blocked (mine is!)
client.Host = "smtp.office365.com";
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = true;
try
{
    client.Send(msg);
    lblText.Text = "Message Sent Succesfully";
}
catch (Exception ex)
{
    lblText.Text = ex.ToString();
}

I have two web applications using the above code and both work fine without any trouble.

Solution 2 - C#

In year of 2020, these code seems to return exception as

System.Net.Mail.SmtpStatusCode.MustIssueStartTlsFirst or The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM

This code is working for me.

            using (SmtpClient client = new SmtpClient()
            {
                Host = "smtp.office365.com",
                Port = 587,
                UseDefaultCredentials = false, // This require to be before setting Credentials property
                DeliveryMethod = SmtpDeliveryMethod.Network,
                Credentials = new NetworkCredential("[email protected]", "password"), // you must give a full email address for authentication 
                TargetName = "STARTTLS/smtp.office365.com", // Set to avoid MustIssueStartTlsFirst exception
                EnableSsl = true // Set to avoid secure connection exception
            })
            {

                MailMessage message = new MailMessage()
                {
                    From = new MailAddress("[email protected]"), // sender must be a full email address
                    Subject = subject,
                    IsBodyHtml = true,
                    Body = "<h1>Hello World</h1>",
                    BodyEncoding = System.Text.Encoding.UTF8,
                    SubjectEncoding = System.Text.Encoding.UTF8,

                };
                var toAddresses = recipients.Split(',');
                foreach (var to in toAddresses)
                {
                    message.To.Add(to.Trim());
                }

                try
                {
                    client.Send(message);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }

Solution 3 - C#

Quick answer: the FROM address must exactly match the account you are sending from, or you will get a error 5.7.1 Client does not have permissions to send as this sender.

My guess is that prevents email spoofing with your Office 365 account, otherwise you might be able to send as [email protected].

Another thing to try is in the authentication, fill in the third field with the domain, like

Dim smtpAuth = New System.Net.NetworkCredential(
    "TheDude", "hunter2password", "MicrosoftOffice365Domain.com")

If that doesn't work, double check that you can log into the account at: https://portal.microsoftonline.com

Yet another thing to note is your Antivirus solution may be blocking programmatic access to ports 25 and 587 as a anti-spamming solution. Norton and McAfee may silently block access to these ports. Only enabling Mail and Socket debugging will allow you to notice it (see below).

One last thing to note, the Send method is Asynchronous. If you call

Dispose
immediately after you call send, your are more than likely closing your connection before the mail is sent. Have your smtpClient instance listen for the OnSendCompleted event, and call dispose from there. You must use SendAsync method instead, the Send method does not raise this event.


Detailed Answer: With Visual Studio (VB.NET or C# doesn't matter), I made a simple form with a button that created the Mail Message, similar to that above. Then I added this to the application.exe.config (in the bin/debug directory of my project). This enables the Output tab to have detailed debug info.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<system.diagnostics>
		<sources>
			<source name="System.Net">
				<listeners>
					<add name="System.Net" />
				</listeners>
			</source>
			<source name="System.Net.Sockets">
				<listeners>
					<add name="System.Net" />
				</listeners>
			</source>
		</sources>
		<switches>
			<add name="System.Net" value="Verbose" />
			<add name="System.Net.Sockets" value="Verbose" />
		</switches>
		<sharedListeners>
			<add name="System.Net"
			  type="System.Diagnostics.TextWriterTraceListener"
			  initializeData="System.Net.log"
			/>
		</sharedListeners>
		<trace autoflush="true" />
	</system.diagnostics>
</configuration>

Solution 4 - C#

Office 365 use two servers, smtp server and protect extended sever.

First server is smtp.office365.com (property Host of smtp client) and second server is STARTTLS/smtp.office365.com (property TargetName of smtp client). Another thing is must put Usedefaultcredential =false before set networkcredentials.

    client.UseDefaultCredentials = False
    client.Credentials = New NetworkCredential("[email protected]", "Password")
    client.Host = "smtp.office365.com"
    client.EnableSsl = true
    client.TargetName = "STARTTLS/smtp.office365.com"
    client.Port = 587
    
    client.Send(mail)

Solution 5 - C#

Have you seen this? https://stackoverflow.com/questions/6656039/sending-email-using-smtp-mail-microsoftonline-com/7009204#7009204

Setting the UseDefaultCredentials after setting the Credentials would be resetting your Credentials property.

Solution 6 - C#

Here is a side note for some that may be searching this thread for an answer to this problem. (Be sure to read cautions at the bottom before implementing this solution.) I was having trouble sending emails for a client to which my MS Office 365 subscription did not have a user or domain for. I was trying to SMTP through my [email protected] 365 account but the .NET mail message was addressed from [email protected]. This is when the "5.7.1 Client does not have permissions" error popped up for me. To remedy, the MailMessage class needed to have the Sender property set to an email address that my supplied SMTP credentials had permission in O365 to "Send As". I chose to use my main account email ([email protected]) as seen in the code below. Keep in mind I could have used ANY email address my O365 account had permission to "send as" (i.e. [email protected], [email protected], etc.)

using System;
using System.Net.Mail;

namespace ConsoleApplication1
{
   class Program
   {
      static void Main(string[] args)
      {
         using (
            MailMessage message = new MailMessage
            {
               To = { new MailAddress("[email protected]", "Recipient 1") },
               Sender = new MailAddress("[email protected]", "Me"),
               From = new MailAddress("[email protected]", "Client"),
               Subject=".net Testing"
               Body="Testing .net emailing",
               IsBodyHtml=true,
            }
         )
         {
            using (
               SmtpClient smtp = new SmtpClient
               {
                  Host = "smtp.office365.com",
                  Port = 587,
                  Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"),
                  EnableSsl = true
               }
            )
            {
               try { smtp.Send(message); }
               catch (Exception excp)
               {
                  Console.Write(excp.Message);
                  Console.ReadKey();
               }
            }
         }
      }
   }
}

Please note SmtpClient is only disposable and able to use the Using block in .NET Framework 4
Users of .NET Framework 2 through 3.5 should use SmtpClient as such...

SmtpClient smtp = new SmtpClient
{
   Host = "smtp.office365.com",
   Port = 587,
   Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"),
   EnableSsl = true
};
try { smtp.Send(message); }
catch (Exception excp)
{
   Console.Write(excp.Message);
   Console.ReadKey();
}

The resulting email's header will look something like this:

Authentication-Results: spf=none (sender IP is )  
   smtp.mailfrom=Me@MyDomain.com;  
Received: from MyPC (192.168.1.1) by  
   BLUPR13MB0036.namprd13.prod.outlook.com (10.161.123.150) with Microsoft SMTP  
   Server (TLS) id 15.1.318.9; Mon, 9 Nov 2015 16:06:58 +0000  
MIME-Version: 1.0  
From: Client <[email protected]>  
Sender: Me <Me@MyDomain.com>  
To: Recipient 1 <[email protected]>  

-- Be Cautious --
Be aware some mail clients may display the Sender address as a note. For example Outlook will display something along these lines in the Reading Pane's header:

> Me <[email protected]> on behalf of Client <[email protected]>

However, so long as the email client the recipient uses isn't total garbage, this shouldn't effect the Reply To address. Reply To should still use the From address. To cover all your bases, you can also utilize the MailMessage.ReplyToList property to afford every opportunity to the client to use the correct reply address.

Also, be aware that some email servers may flat out reject any emails that are Sent On Behalf of another company siting Domain Owner Policy Restrictions. Be sure to test thoroughly and look for any bounce backs. I can tell you that my personal Hotmail (mail.live.com) email account is one that will reject messages I send on behalf of a certain client of mine but others clients go through fine. Although I suspect that it has something to do with my client's domain TXT "spf1" records, I do not have an answer as to why it will reject emails sent on behalf of one domain versus another. Maybe someone who knows can shed some light on the subject?

Solution 7 - C#

I've ported c# code used to work against smtp.google.com:587 to work via office365 without success. Tried all combinations of Credential before/after using Ssl and almost every recommendation made on the Internet - w/o success (got 5.7.1 .... error).

Finally got this line from somewhere as last resort, just before .Send(message)

smtpClient.TargetName = "STARTTLS/smtp.office365.com";

Since then - every send() is big success.

Solution 8 - C#

Finally, Works!

Put smtpClient.UseDefaultCredentials = false; after smtpClient.Credentials = credentials; then problem resolved!

            SmtpClient smtpClient = new SmtpClient(smtpServerName);                          
            System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(smtpUName, smtpUNamePwd);

            smtpClient.Credentials = credentials;
            smtpClient.UseDefaultCredentials = false;  <-- Set This Line After Credentials

            smtpClient.Send(mailMsg);
            smtpClient = null;
            mailMsg.Dispose();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdam StewartView Question on Stackoverflow
Solution 1 - C#SanjeevView Answer on Stackoverflow
Solution 2 - C#JirapongView Answer on Stackoverflow
Solution 3 - C#The DudeView Answer on Stackoverflow
Solution 4 - C#Carlos GalíndezView Answer on Stackoverflow
Solution 5 - C#Phil SayersView Answer on Stackoverflow
Solution 6 - C#ShaneLSView Answer on Stackoverflow
Solution 7 - C#Joe FrankView Answer on Stackoverflow
Solution 8 - C#YeongView Answer on Stackoverflow