3

I am sending a mail using gmail smtp : Host : smtp.gmail.com Port : 587

Getting exception while sending mail using gmail smtp in MVC application. Below code used to send mail :

public static int SendMail(string StrFromAdd, string StrEmailTo, string StrSubject, string StrContents,
        string SMTPServer, int SMTPPort, string SMTPUserName, string SMTPPassword,
        string attachment = "", string CC = "", string BCC = "")
    {
        try
        {
            AlternateView AV = null;
            System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient();
            System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
            System.Net.Mail.MailAddress fromAddress = new System.Net.Mail.MailAddress(StrFromAdd, "Test");
            smtpClient.Host = SMTPServer;
            smtpClient.Port = SMTPPort;
            smtpClient.Credentials = new System.Net.NetworkCredential(SMTPUserName, SMTPPassword);

            smtpClient.EnableSsl = true;

            message.From = fromAddress;

            if (attachment != null)
            {
                string[] attachmentsarr = attachment.Split(';');
                foreach (string attach in attachmentsarr)
                {
                    if (attach != "")
                        message.Attachments.Add(new Attachment(attach));
                }
            }

            string pattern = @"^((([\w]+\.[\w]+)+)|([\w]+))@(([\w]+\.)+)([A-Za-z]{1,3})$";

            if (StrEmailTo != "")
            {
                if (StrEmailTo.IndexOf(',') > -1)
                {
                    string[] _strArrstrEmailTo = StrEmailTo.Split(',');
                    foreach (object objBCCEmailID in _strArrstrEmailTo)
                        if (Regex.IsMatch(objBCCEmailID.ToString().Trim(), pattern))
                            message.To.Add(new System.Net.Mail.MailAddress(objBCCEmailID.ToString().Trim()));

                }
                else
                    message.To.Add(new System.Net.Mail.MailAddress(StrEmailTo.ToString().Trim()));
            }

            if (CC != "")
            {
                if (CC.IndexOf(',') > -1)
                {
                    string[] _strArrstrEmailCC = CC.Split(',');
                    foreach (object objBCCEmailID in _strArrstrEmailCC)
                        if (Regex.IsMatch(objBCCEmailID.ToString().Trim(), pattern))
                            message.CC.Add(new System.Net.Mail.MailAddress(objBCCEmailID.ToString().Trim()));

                }
                else
                    message.CC.Add(new System.Net.Mail.MailAddress(CC.ToString().Trim()));
            }

            if (BCC != "")
            {
                if (BCC.IndexOf(',') > -1)
                {
                    string[] _strArrstrEmailBCC = BCC.Split(',');
                    foreach (object objBCCEmailID in _strArrstrEmailBCC)
                        if (Regex.IsMatch(objBCCEmailID.ToString().Trim(), pattern))
                            message.Bcc.Add(new System.Net.Mail.MailAddress(objBCCEmailID.ToString().Trim()));

                }
                else
                    message.Bcc.Add(new System.Net.Mail.MailAddress(BCC.ToString().Trim()));
            }
            // This is added for custom form & email template image
            List<string> ImageFiles = Common.GetImagesInHTMLString(StrContents);
            if (ImageFiles != null && ImageFiles.Count > 0)
            {
                string addStrContents = string.Empty;

                for (int i = 0; i < ImageFiles.Count; i++)
                {
                    // this is for custom form
                    if (ImageFiles[i].Contains("CustomFormImage"))
                    {
                        string Path = Regex.Match(ImageFiles[i], "<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase).Groups[1].Value;
                        int pos = Path.LastIndexOf("\\") + 1;
                        string FullPath = HttpContext.Current.Server.MapPath("~/img/CustomFormImage/" + Path.Substring(pos, Path.Length - pos));
                        if (System.IO.File.Exists(FullPath))
                        {
                            //addStrContents = addStrContents + "<img style='width:100px;height:100px;' src=\"cid:" + Path.Substring(pos, Path.Length - pos).Split('.')[0] + "\">" + Environment.NewLine;
                            StrContents = StrContents.Replace(Path, "cid:" + Path.Substring(pos, Path.Length - pos).Split('.')[0]);
                        }
                    }
                    // this is for email template image
                    else if (ImageFiles[i].Contains("EmailHeaderFooterImgs"))
                    {
                        string Path = Regex.Match(ImageFiles[i], "<img.+?src =[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase).Groups[1].Value;
                        int pos = Path.LastIndexOf("\\") + 1;
                        if (System.IO.File.Exists(Path))
                        {
                            //addStrContents = addStrContents + "<img style='width:100px;height:100px;' src=\"cid:" + Path.Substring(pos, Path.Length - pos).Split('.')[0] + "\">" + Environment.NewLine;
                            StrContents = StrContents.Replace(Path, "cid:" + Path.Substring(pos, Path.Length - pos).Split('.')[0]);
                        }
                    }
                }
                AV = AlternateView.CreateAlternateViewFromString(StrContents, null, MediaTypeNames.Text.Html);
                for (int i = 0; i < ImageFiles.Count; i++)
                {
                    // this is for custom form
                    if (ImageFiles[i].Contains("CustomFormImage"))
                    {
                        string Path = Regex.Match(ImageFiles[i], "<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase).Groups[1].Value;
                        int pos = Path.LastIndexOf("\\") + 1;
                        string FullPath = HttpContext.Current.Server.MapPath("~/img/CustomFormImage/" + Path.Substring(pos, Path.Length - pos));
                        if (System.IO.File.Exists(FullPath))
                        {
                            //FileStream fs = new FileStream(FullPath, FileMode.Open, FileAccess.Read);
                            //Attachment a = new Attachment(fs, Path.Substring(pos, Path.Length - pos), MediaTypeNames.Application.Octet);
                            //message.Attachments.Add(a);
                            //addStrContents = addStrContents + "<img src=\"cid:" + Path.Substring(pos, Path.Length - pos).Split('.')[0] + "\">" + Environment.NewLine;
                            LinkedResource Img = new LinkedResource(FullPath, MediaTypeNames.Image.Jpeg);
                            Img.ContentId = Path.Substring(pos, Path.Length - pos).Split('.')[0];
                            AV.LinkedResources.Add(Img);
                        }
                    }
                    // this is for email template image
                    else if (ImageFiles[i].Contains("EmailHeaderFooterImgs"))
                    {
                        string Path = Regex.Match(ImageFiles[i], "<img.+?src =[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase).Groups[1].Value;
                        int pos = Path.LastIndexOf("\\") + 1;
                        if (HttpContext.Current != null)
                        {
                            string FullPath = HttpContext.Current.Server.MapPath("~/EmailHeaderFooterImgs/" + Path.Substring(pos, Path.Length - pos));
                            if (System.IO.File.Exists(Path))
                            {
                                LinkedResource Img = new LinkedResource(Path, MediaTypeNames.Image.Jpeg);
                                Img.ContentId = Path.Substring(pos, Path.Length - pos).Split('.')[0];
                                AV.LinkedResources.Add(Img);
                            }
                        }
                    }
                }
            }

            message.Subject = StrSubject;
            message.IsBodyHtml = true;
            if (AV != null)
                message.AlternateViews.Add(AV);
            else
                message.Body = StrContents;

            smtpClient.Send(message);
            message.Dispose();
            return 1;
        }
        catch (Exception ex)
        {

        }
    }

Below is stack track :

    System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. System.ComponentModel.Win32Exception: The function requested is not supported
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Mail.SmtpConnection.Flush()
   at System.Net.Mail.ReadLinesCommand.Send(SmtpConnection conn)
   at System.Net.Mail.EHelloCommand.Send(SmtpConnection conn, String domain)
   at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at MVC.Common.SendMails.SendMail(String StrFromAdd, String StrEmailTo, String StrSubject, String StrContents, String SMTPServer, Int32 SMTPPort, String SMTPUserName, String SMTPPassword, String attachment, String CC, String BCC) in SendMails.cs:line 296

Note : Same code is working in another application which is hosted in same server and also used same gmail configuration to send mails.

Shreekant
  • 111
  • 2
  • 11

3 Answers3

3

Assuming that your code is compiled for (e.g.) .NET Framework 4.7.2 then make sure your Web.config includes:

<httpRuntime targetFramework="4.7.2" />

If targetFramework is too low, or missing, the compiled code will still automatically try to request TLS 1.2 (which happens from .NET Framework 4.7 upwards) but the runtime will not support it, causing the error.

(Credit to this SO answer, which is what made me realise what was going wrong here - though that question and this one are not duplicates.)

MikeBeaton
  • 3,314
  • 4
  • 36
  • 45
  • I originally put this answer here https://stackoverflow.com/q/38527662 but I've moved it to here as I think it's more definitely relevant here. I've just left a comment with a link back here at the other question. – MikeBeaton Nov 21 '20 at 17:55
1

I solved this problem changing security protocol before send

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Lucas Prestes
  • 362
  • 1
  • 4
  • 19
0

Add this code before sending email:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)12288 | (SecurityProtocolType)3072 | (SecurityProtocolType)768 | SecurityProtocolType.Tls;

  • 1
    Please always provide an explanation on what your code is doing, why it should be added... this improves the quality of your answer – Alex Berger Nov 18 '22 at 09:38