abcd3fg
abcd3fg

Reputation: 3

Won't send mail message - C#

Okay; I can't seem to send a mail message. I'm running this as a console application:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace Email
{
    class Program
    {
        static void EMail(string ToAddress, string Subject, string Body, string FromAddress, string Host, int Port, string Username, string Password)
        {
            System.Net.Mail.SmtpClient SMTPClient = new System.Net.Mail.SmtpClient(Host, Port);
            System.Net.Mail.MailMessage Message = new System.Net.Mail.MailMessage();
            Message.To.Add(new System.Net.Mail.MailAddress(ToAddress));
            Message.From = new System.Net.Mail.MailAddress(FromAddress);
            Message.Body = Body;
            Message.Subject = Subject;
            SMTPClient.EnableSsl = true;
            SMTPClient.Credentials = new System.Net.NetworkCredential(Username, Password);
            SMTPClient.Send(Message);
            SMTPClient.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(FinishedSending);
        }
        static void FinishedSending(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            Console.WriteLine("DONE!");
        }
        static void Main(string[] args)
        {
            EMail("***********", "Hi!", "This is a test, Sent from a C# application.", "******", "smtp.gmail.com", 465, "****************", "**************");
            Console.ReadLine();
        }
    }
}

I'm not getting any errors, I'm not recieving it in my gmail account, And it's not writing "DONE!". I have allowed port 465, outcoming and incoming. Telnetting smtp.gmail.com on port 465 results in a blank command prompt window. Thanks.

Upvotes: 0

Views: 6507

Answers (4)

AlwaysLearning
AlwaysLearning

Reputation: 8809

The reason it doesn't work is because you're targeting port 465. Using EnableSsl with port 25 (although not with Gmail) or port 587 should work for you.

SMTPS on port 465, or "Implicit SSL" as Microsoft calls it in a lot of places, is not supported by the SmtpClient class. The EnableSsl property controls whether or not the class will look for and use the STARTTLS command after an unencrypted connection has been established.

As per the Microsoft SmtpClient.EnableSsl Property documentation:

The SmtpClient class only supports the SMTP Service Extension for Secure SMTP over Transport Layer Security as defined in RFC 3207. In this mode, the SMTP session begins on an unencrypted channel, then a STARTTLS command is issued by the client to the server to switch to secure communication using SSL. See RFC 3207 published by the Internet Engineering Task Force (IETF) for more information.

An alternate connection method is where an SSL session is established up front before any protocol commands are sent. This connection method is sometimes called SMTP/SSL, SMTP over SSL, or SMTPS and by default uses port 465. This alternate connection method using SSL is not currently supported.

If you really need to use SMTPS over port 465 there are solutions using the deprecated System.Web.Mail classes that use CDONTS behind the scenes, e.g. https://stackoverflow.com/a/1014876.

Upvotes: 0

Egor
Egor

Reputation: 359

Go to Task -> Actions - > Edit Action and set "Start in (optional)" to folder where the executable file is.

Upvotes: 1

Iron Savior
Iron Savior

Reputation: 4368

I think that System.Net.Mail.SmtpClient::Send() may not be as synchronous as it should be. I was using this class in a powershell script that was to be run by the Task Scheduler. When running the script from a powershell console, I always received the message. However, when running the script as a scheduled task, I would not.

I resolved the problem by having the script sleep for 1 second after sending--I suspect the SMTP session was being killed by powershell shutting down at the end of the script, which doesn't happen when running it from an interactive session.

I know it's sloppy, but I haven't figured out a better way to make sure it's actually finished. Maybe there's a buffer that has to be flushed?

An alternative might be to call Send() with a bogus message after you send the actual message. I found that the message was consistently sent if I did this. This is still sloppy, but I find it a little bit less sloppy because it is more likely to actually require the buffers to be flushed before sending while waiting an arbitrary amount of time will definitely not cause it.

Upvotes: 0

lahsrah
lahsrah

Reputation: 9173

Email should be going through if there is no exception.

It is not printing "DONE!" because you are hooking into the event after calling Send() method. Hook in the even before calling send.

Edit: And yes it should be SendAsync. Send is synchronous.

Also try these parameters in this order:

smtpClient.EnableSsl = true;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = (...)

This code works for me, in a new Winforms application:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }



        static void smtpClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            var state = e.UserState;
            //"Done"
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var smtpClient = new SmtpClient("smtp.gmail.com", 587)
            {
                EnableSsl = true,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential("[email protected]", "mypassword")
            };

            var message = new MailMessage("[email protected]", "[email protected]", "Subject", "body");

            smtpClient.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
            smtpClient.SendAsync(message, new object());

        }
    }

Upvotes: 4

Related Questions