0

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.

abcd3fg
  • 3
  • 1
  • 5
  • put the code around a `try{} catch{}` block, so you can identify the specific error you are receiving.... – Cacho Santa Jan 13 '13 at 23:15
  • are you SURE that SMPTClient.Send() isn't throwing an exception? i'd wrap a try/catch around that and see if you don't catch an exception there... – Mike Corcoran Jan 13 '13 at 23:15
  • 1
    Have you stepped though the code in the debugger to check that it is getting as far as sending the e-mail without throwing an exception? – ChrisF Jan 13 '13 at 23:16
  • 1
    `Send` is synchronous and does not raised the `SendCompleted` event. – Mike Zboray Jan 13 '13 at 23:17
  • I modified the send and event so it is now like this: ` SMTPClient.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(FinishedSending); SMTPClient.SendAsync(Message, "Test Message");` – abcd3fg Jan 13 '13 at 23:20

4 Answers4

4

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("myEmail@gmail.com", "mypassword")
            };

            var message = new MailMessage("myEmail@gmail.com", "myEmail@gmail.com", "Subject", "body");

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

        }
    }
lahsrah
  • 8,073
  • 4
  • 32
  • 58
  • The email isn't going through because i'm not receiving it in my email er-web-client. – abcd3fg Jan 13 '13 at 23:21
  • Also the Gmail SMTP server is a little complicated, see the answer to this question http://stackoverflow.com/questions/32260/sending-email-in-net-through-gmail UseDefaultCredentials = false might also be needed. You may also want to try port 587 instead? I had some code that worked with gmail but took me a lot of trial and error and fiddling with SmtpClient settings. – lahsrah Jan 13 '13 at 23:25
  • Yeah, I tried 587 and got "DONE!", but nothing in my inbox...yet. – abcd3fg Jan 13 '13 at 23:29
  • Just realized i had the wrong password for a minute. Fixed the password, got the "DONE!" message, but still nothing in my inbox. – abcd3fg Jan 13 '13 at 23:31
  • The properties in that order didn't work either. Still getting the done message, nothing in my inbox. – abcd3fg Jan 13 '13 at 23:42
  • See the whole example in my answer above. make sure you follow it as is. What kind of application are you doing this in? Console App may quit before the email gets sent, try with WinForm app like above or use Send() instead of SendAsync(). Also make sure you use your own GMail address for "FROM". I tried with my Gmail address for FROM and TO and it worked above. – lahsrah Jan 13 '13 at 23:46
  • I'm using a Console Application but i have `Console.Read()` at the end as to not close the application. It's still not working; and i have no idea why. – abcd3fg Jan 13 '13 at 23:50
  • That didn't work for me either. Console app is waiting for user input when you do Console.Read() I am not sure why exactly but I think it blocks there and SendAsync never returned if you put debugger. I suggest you switch to Send instead of SendAsync – lahsrah Jan 13 '13 at 23:51
  • It isn't working in a windows form application either. Do you want me to post the entire code again? – abcd3fg Jan 14 '13 at 00:13
  • copy my entire code, paste it into your app, change to your gmail username and password only. Then debug and put break point in SendCompleted. – lahsrah Jan 14 '13 at 00:15
1

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

Egor
  • 251
  • 2
  • 2
0

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.

Iron Savior
  • 3,940
  • 3
  • 21
  • 30
0

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.

Community
  • 1
  • 1
AlwaysLearning
  • 4,396
  • 4
  • 21
  • 28