)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » Smtp (Ia.Cl.Models)

Public general use code classes and xml files that we've compiled and used over the years:

SMTP Server Support Class

    1: using System.Diagnostics;
    2: using System.Net;
    3: using System.Text;
    4: using MimeKit;
    5: using MailKit.Net.Smtp;
    6: using MailKit.Security;
    7: using System.Threading.Tasks;
    8:  
    9: namespace Ia.Cl.Models
   10: {
   11:     ////////////////////////////////////////////////////////////////////////////
   12:  
   13:     /// <summary publish="true">
   14:     /// SMTP Server Support Class
   15:     /// </summary>
   16:     /// <remarks> 
   17:     /// Copyright © 2001-2025 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   18:     ///
   19:     /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
   20:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   21:     ///
   22:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   23:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   24:     /// 
   25:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   26:     /// 
   27:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   28:     /// </remarks> 
   29:     public class Smtp
   30:     {
   31:         private enum SubType { Plain, Html };
   32:  
   33:         ////////////////////////////////////////////////////////////////////////////
   34:  
   35:         /// <summary>
   36:         ///
   37:         /// </summary>
   38:         public Smtp() { }
   39:  
   40:         ////////////////////////////////////////////////////////////////////////////
   41:  
   42:         /// <summary>
   43:         ///
   44:         /// </summary>
   45:         public static async Task<Ia.Cl.Models.Result> SendPlain(string name, string email, string subject, string content)
   46:         {
   47:             var result = await SendAsync(name, email, subject, content, SubType.Plain);
   48:  
   49:             return result;
   50:         }
   51:  
   52:         ////////////////////////////////////////////////////////////////////////////
   53:  
   54:         /// <summary>
   55:         ///
   56:         /// </summary>
   57:         public static async Task<Ia.Cl.Models.Result> SendHtml(string name, string email, string subject, string content)
   58:         {
   59:             var result = await SendAsync(name, email, subject, content, SubType.Html);
   60:  
   61:             return result;
   62:         }
   63:  
   64:         ////////////////////////////////////////////////////////////////////////////
   65:  
   66:         /// <summary>
   67:         ///
   68:         /// </summary>
   69:         private static async Task<Ia.Cl.Models.Result> SendAsync(string name, string email, string subject, string content, SubType mailType)
   70:         {
   71:             bool smtpServerEnableSsl;
   72:             string smtpServerHost, smtpServerUserName, smtpServerUser, smtpServerPassword;
   73:  
   74:             /* 
   75:              * appsettings.json:
   76:   "AppSettings": {
   77:     "SmtpServerEnableSsl": "false|true",
   78:     "SmtpServerHost": "*********",
   79:     "SmtpServerUserName": ""*********",",
   80:     "SmtpServerUser": "*********",
   81:     "SmtpServerPassword": "*********",
   82:   }
   83:             */
   84:  
   85:             smtpServerEnableSsl = bool.Parse(Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:SmtpServerEnableSsl"));
   86:             smtpServerHost = Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:SmtpServerHost");
   87:             smtpServerUserName = Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:SmtpServerUserName");
   88:             smtpServerUser = Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:SmtpServerUser");
   89:             smtpServerPassword = Ia.Cl.Models.ApplicationConfiguration.GetSetting("AppSettings:SmtpServerPassword");
   90:  
   91:             var result = await SendAsync(name, email, subject, content, smtpServerHost, smtpServerUserName, smtpServerUser, smtpServerPassword, smtpServerEnableSsl, mailType);
   92:  
   93:             return result;
   94:         }
   95:  
   96:         ////////////////////////////////////////////////////////////////////////////
   97:  
   98:         /// <summary>
   99:         ///
  100:         /// </summary>
  101:         private static async Task<Ia.Cl.Models.Result> SendAsync(string name, string email, string subject, string content, string smtpServerHost, string smtpServerUserName, string smtpServerUser, string smtpServerPassword, bool smtpServerEnableSsl, SubType subType)
  102:         {
  103:             // https://github.com/jstedfast/MailKit/blob/master/Documentation/Examples/SmtpExamples.cs
  104:  
  105:             int port;
  106:             var result = new Ia.Cl.Models.Result();
  107:  
  108:             var message = new MimeMessage();
  109:  
  110:             message.From.Add(new MailboxAddress(smtpServerUserName, smtpServerUser));
  111:             message.To.Add(new MailboxAddress(name, email));
  112:             message.Subject = subject;
  113:  
  114:             if (subType == SubType.Html) message.Body = new TextPart("html") { Text = content };
  115:             else /*if (subType == SubType.Plain)*/ message.Body = new TextPart("plain") { Text = content };
  116:  
  117:             var secureSocketOptions = new SecureSocketOptions();
  118:  
  119:             if (smtpServerEnableSsl)
  120:             {
  121:                 secureSocketOptions = SecureSocketOptions.Auto;
  122:             }
  123:             else secureSocketOptions = SecureSocketOptions.None;
  124:  
  125:             port = 587;
  126:  
  127:             if (smtpServerHost == "smtp.gmail.com")
  128:             {
  129:                 port = 465;
  130:                 secureSocketOptions = SecureSocketOptions.SslOnConnect;
  131:             }
  132:  
  133:             using (var smtpClient = new SmtpClient())
  134:             {
  135:                 try
  136:                 {
  137:                     await smtpClient.ConnectAsync(smtpServerHost, port, secureSocketOptions);
  138:                 }
  139:                 catch (SmtpCommandException ex)
  140:                 {
  141:                     result.AddError("Error trying to connect: " + ex.Message);
  142:                     result.AddError("StatusCode: " + ex.StatusCode);
  143:  
  144:                     return result;
  145:                 }
  146:                 catch (SmtpProtocolException ex)
  147:                 {
  148:                     result.AddError("Protocol error while trying to connect: " + ex.Message);
  149:  
  150:                     return result;
  151:                 }
  152:  
  153:                 // below: Not all SMTP servers support authentication, but GMail does.
  154:                 if (smtpClient.Capabilities.HasFlag(SmtpCapabilities.Authentication))
  155:                 {
  156:                     try
  157:                     {
  158:                         await smtpClient.AuthenticateAsync(smtpServerUser, smtpServerPassword);
  159:                     }
  160:                     catch (AuthenticationException ex)
  161:                     {
  162:                         result.AddError("Invalid user name or password.");
  163:  
  164:                         return result;
  165:                     }
  166:                     catch (SmtpCommandException ex)
  167:                     {
  168:                         result.AddError("Error trying to authenticate: " + ex.Message);
  169:                         result.AddError("StatusCode: " + ex.StatusCode);
  170:  
  171:                         return result;
  172:                     }
  173:                     catch (SmtpProtocolException ex)
  174:                     {
  175:                         result.AddError("Protocol error while trying to authenticate: " + ex.Message);
  176:  
  177:                         return result;
  178:                     }
  179:                 }
  180:  
  181:                 try
  182:                 {
  183:                     await smtpClient.SendAsync(message);
  184:  
  185:                     result.AddSuccess("Email sent to " + email + ".");
  186:                 }
  187:                 catch (SmtpCommandException ex)
  188:                 {
  189:                     result.AddError("Error sending message: " + ex.Message);
  190:                     result.AddError("StatusCode: " + ex.StatusCode);
  191:  
  192:                     switch (ex.ErrorCode)
  193:                     {
  194:                         case SmtpErrorCode.RecipientNotAccepted:
  195:                             result.AddError("Recipient not accepted: " + ex.Mailbox);
  196:                             break;
  197:                         case SmtpErrorCode.SenderNotAccepted:
  198:                             result.AddError("Sender not accepted: " + ex.Mailbox);
  199:                             break;
  200:                         case SmtpErrorCode.MessageNotAccepted:
  201:                             result.AddError("Message not accepted.");
  202:                             break;
  203:                     }
  204:                 }
  205:                 catch (SmtpProtocolException ex)
  206:                 {
  207:                     result.AddError("Protocol error while sending message: " + ex.Message);
  208:                 }
  209:  
  210:                 await smtpClient.DisconnectAsync(true);
  211:  
  212:                 return result;
  213:             }
  214:         }
  215:  
  216:         ////////////////////////////////////////////////////////////////////////////
  217:         ////////////////////////////////////////////////////////////////////////////
  218:     }
  219: }