0

I am using the System.Net.Mail library to send e-mails through a remote desktop connection. The e-mails are sent correctly if the address is my company's, but for all other addresses, e-mails are not sent. I do not get any exception or error, they just never reach the address, or go to Spam/Junk. When i synchronize my 'Sent' folder, the e-mail appears.

The code i am using to send e-mails is below

    var smtpClient = new System.Net.Mail.SmtpClient(hostName)
    {
        EnableSsl = false,
        DeliveryMethod = SmtpDeliveryMethod.Network
    };
    smtpClient.Credentials = new NetworkCredential(userName, password);
    smtpClient.SendAndSaveMessageToIMAP(mailMessage, hostName, port, userName, password, "INBOX.Sent");

and the following

        static System.IO.StreamWriter sw = null;
        static System.Net.Sockets.TcpClient tcpc = null;
        static System.Net.Security.SslStream ssl = null;
        static string path;
        static int bytes = -1;
        static byte[] buffer;
        static System.Text.StringBuilder sb = new System.Text.StringBuilder();
        static byte[] dummy;
        private static readonly bool IsRunningInDotNetFourPointFive = SendMethod.GetParameters().Length == 3;

        private static readonly System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
        private static readonly System.Type MailWriter = typeof(System.Net.Mail.SmtpClient).Assembly.GetType("System.Net.Mail.MailWriter");
        private static readonly System.Reflection.ConstructorInfo MailWriterConstructor = MailWriter.GetConstructor(Flags, null, new[] { typeof(System.IO.Stream) }, null);
        private static readonly System.Reflection.MethodInfo CloseMethod = MailWriter.GetMethod("Close", Flags);
        private static readonly System.Reflection.MethodInfo SendMethod = typeof(System.Net.Mail.MailMessage).GetMethod("Send", Flags);

        public static void SendAndSaveMessageToIMAP(this System.Net.Mail.SmtpClient self, System.Net.Mail.MailMessage mailMessage, string imapServer, int imapPort, string userName, string password, string sentFolderName)
        {
            try
            {
                path = System.Environment.CurrentDirectory + "\\emailresponse.txt";

                if (System.IO.File.Exists(path))
                    System.IO.File.Delete(path);

                sw = new System.IO.StreamWriter(System.IO.File.Create(path));

                tcpc = new System.Net.Sockets.TcpClient(imapServer, imapPort);

                ssl = new System.Net.Security.SslStream(tcpc.GetStream());

                try
                {
                    ssl.AuthenticateAsClient(imapServer);
                }
                catch (Exception ex)
                {
                    throw;
                }

                SendCommandAndReceiveResponse("");

                SendCommandAndReceiveResponse(string.Format("$ LOGIN {1} {2}  {0}", System.Environment.NewLine, userName, password));

                using (var m = mailMessage.RawMessage())
                {
                    m.Position = 0;
                    var sr = new System.IO.StreamReader(m);
                    var myStr = sr.ReadToEnd();
                    SendCommandAndReceiveResponse(string.Format("$ APPEND {1} (\\Seen) {{{2}}}{0}", System.Environment.NewLine, sentFolderName, myStr.Length));
                    SendCommandAndReceiveResponse(string.Format("{1}{0}", System.Environment.NewLine, myStr));
                }
                SendCommandAndReceiveResponse(string.Format("$ LOGOUT{0}", System.Environment.NewLine));
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("error: " + ex.Message);
            }
            finally
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }
                if (ssl != null)
                {
                    ssl.Close();
                    ssl.Dispose();
                }
                if (tcpc != null)
                {
                    tcpc.Close();
                }
            }
            self.Send(mailMessage);
        }

        private static void SendCommandAndReceiveResponse(string command)
        {
            try
            {
                if (command != "")
                {
                    if (tcpc.Connected)
                    {
                        dummy = System.Text.Encoding.ASCII.GetBytes(command);
                        ssl.Write(dummy, 0, dummy.Length);
                    }
                    else
                    {
                        throw new System.ApplicationException("TCP CONNECTION DISCONNECTED");
                    }
                }
                ssl.Flush();

                buffer = new byte[2048];
                bytes = ssl.Read(buffer, 0, 2048);
                sb.Append(System.Text.Encoding.ASCII.GetString(buffer));

                sw.WriteLine(sb.ToString());
                sb = new System.Text.StringBuilder();
            }
            catch (System.Exception ex)
            {
                throw new System.ApplicationException(ex.Message);
            }
        }

        public static System.IO.MemoryStream RawMessage(this System.Net.Mail.MailMessage self)
        {
            var result = new System.IO.MemoryStream();
            var mailWriter = MailWriterConstructor.Invoke(new object[] { result });
            SendMethod.Invoke(self, Flags, null, IsRunningInDotNetFourPointFive ? new[] { mailWriter, true, true } : new[] { mailWriter, true }, null);
            result = new System.IO.MemoryStream(result.ToArray());
            CloseMethod.Invoke(mailWriter, Flags, null, new object[] { }, null);
            return result;
        }

Any help would be highly appreciated.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 1
    "or go to spam/junk", in the recipients mailbox or the server/outgoing? – Lasse V. Karlsen Apr 15 '20 at 09:12
  • Thank you for the reply. I am talking about the recipient. If I send an e-mail with my account A, to my account B through the remote, with this code, it appears in "Sent" folder of A, but it appears nowhere in B's mailbox. I actually don't know how I can check if it is being blocked by the server, for any reason. – George Oik Apr 15 '20 at 09:40
  • 1
    Email is unfortunately a very "shouting in the woods" type of problem, you don't have the tools available to you to figure out if the recipient actually got the message (yet), or that it wasn't put into the spam folder on the recipient end. What you should do is making sure you adhere to email standards, such as SPF, which makes it less likely the recipient software will auto-flag it as spam. – Lasse V. Karlsen Apr 15 '20 at 09:57
  • Your code stores the message in a mailbox, one called INBOX.Sent. It doesn't actually send the message to anyone, it just stores the message in a mailbox. If you want to send it, you have to use a different connection, typically connect to port 587 and issue commands such as MAIL FROM: and RCPT TO:. That mailbox called Sent has a suggestive name, but storing the message there doesn't make the suggestion be true, it's just a suggestive name. – arnt Apr 15 '20 at 20:23
  • Thank you for your response. There is actually a 'self.Send(mailMessage);' that attempts to send the mail. But yes, before this I am also attempting to append the e-mail to my Sent folder, because it will not appear any other way. I will try your suggestion to also send the e-mail by issuing commands, thank you! – George Oik Apr 16 '20 at 06:40

0 Answers0