Reputation: 1
I'm encountering an issue while trying to send emails from my .NET application using the SmtpClient
class. Even though my credentials are correct, I keep getting the following error:
System.Net.Mail.SmtpException: Service not available, closing transmission channel. The server response was: Service not available
Sometimes, after multiple attempts, I also get a timeout error.
What I've tried:
Despite these efforts, the issue persists. Below is the relevant code snippet:
public class EmailService
{
private readonly IConfiguration _configuration;
private readonly ILogger<EmailService> _logger;
public EmailService(IConfiguration configuration, ILogger<EmailService> logger)
{
_configuration = configuration;
_logger = logger;
}
public async Task<EmailResponse> SendEmailAsync(EmailRequest emailRequest)
{
using (MailMessage mailMessage = new MailMessage())
{
mailMessage.From = new MailAddress(emailRequest.Sender);
foreach (var recipient in emailRequest.Receipient)
{
mailMessage.To.Add(new MailAddress(recipient));
}
mailMessage.Subject = emailRequest.Subject;
mailMessage.Body = emailRequest.Body;
var configurationKeys = _configuration.GetSection("EmailConfig").Get<EmailConfig>();
if (configurationKeys == null)
{
_logger.LogError("No email credentials available.");
throw new ArgumentNullException(nameof(configurationKeys), "No email credentials available.");
}
var smtpClient = new SmtpClient("smtp.gmail.com")
{
Port = 587,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(configurationKeys.Username, configurationKeys.Password),
EnableSsl = configurationKeys.EnableSSL?.ToLower() == "true",
};
try
{
await smtpClient.SendMailAsync(mailMessage);
_logger.LogInformation("Email sent successfully.");
return new EmailResponse { Status = "successful", Message = "Email sent successfully." };
}
catch (SmtpException smtpEx)
{
_logger.LogError(smtpEx, "SMTP error occurred while sending email.");
return new EmailResponse { Status = "failed", Message = smtpEx.Message };
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred while sending email.");
return new EmailResponse { Status = "failed", Message = ex.Message };
}
}
}
}
Upvotes: 0
Views: 61
Reputation: 1
Yep, the issue is not from the code, but has to do with security, because my endpoint is http when I send the email, it fails when deployed and make the request where it has a valid https endpoint it goes through successfully.
Upvotes: 0
Reputation: 12749
You could try this below code:
using System;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
namespace EmailSenderProject
{
public class Program
{
public static async Task Main(string[] args)
{
// Set up configuration and logging
var serviceProvider = new ServiceCollection()
.AddLogging(configure => configure.AddConsole())
.AddSingleton<IConfiguration>(new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build())
.BuildServiceProvider();
var logger = serviceProvider.GetService<ILogger<Program>>();
var configuration = serviceProvider.GetService<IConfiguration>();
var emailService = new EmailService(configuration, logger);
var emailRequest = new EmailRequest
{
Sender = "sender address",
Receipient = new[] { "receiver address" },
Subject = "Test Email",
Body = "This is a test email sent from a .NET application."
};
var response = await emailService.SendEmailAsync(emailRequest);
Console.WriteLine(response.Message);
}
}
public class EmailService
{
private readonly IConfiguration _configuration;
private readonly ILogger<Program> _logger;
public EmailService(IConfiguration configuration, ILogger<Program> logger)
{
_configuration = configuration;
_logger = logger;
}
public async Task<EmailResponse> SendEmailAsync(EmailRequest emailRequest)
{
using (var mailMessage = new MailMessage())
{
mailMessage.From = new MailAddress(emailRequest.Sender);
foreach (var recipient in emailRequest.Receipient)
{
mailMessage.To.Add(new MailAddress(recipient));
}
mailMessage.Subject = emailRequest.Subject;
mailMessage.Body = emailRequest.Body;
var configurationKeys = _configuration.GetSection("EmailConfig").Get<EmailConfig>();
if (configurationKeys == null)
{
_logger.LogError("No email credentials available.");
throw new ArgumentNullException(nameof(configurationKeys), "No email credentials available.");
}
using (var smtpClient = new SmtpClient("smtp.gmail.com"))
{
smtpClient.Port = 587; // Make sure the port is 587 for TLS
smtpClient.UseDefaultCredentials = false; // This should be false since you are providing credentials
smtpClient.Credentials = new NetworkCredential(configurationKeys.Username, configurationKeys.Password);
smtpClient.EnableSsl = true; // Ensure SSL is enabled
try
{
await smtpClient.SendMailAsync(mailMessage);
_logger.LogInformation("Email sent successfully.");
return new EmailResponse { Status = "successful", Message = "Email sent successfully." };
}
catch (SmtpException smtpEx)
{
_logger.LogError(smtpEx, "SMTP error occurred while sending email.");
return new EmailResponse { Status = "failed", Message = smtpEx.Message };
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred while sending email.");
return new EmailResponse { Status = "failed", Message = ex.Message };
}
}
}
}
}
public class EmailRequest
{
public string Sender { get; set; }
public string[] Receipient { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
public class EmailResponse
{
public string Status { get; set; }
public string Message { get; set; }
}
public class EmailConfig
{
public string Username { get; set; }
public string Password { get; set; }
public string EnableSSL { get; set; }
}
}
And make sure you have enabled 2FA on google account you are using and set up the app password.
https://support.google.com/accounts/answer/185833
appsettings.json:
{
"EmailConfig": {
"Username": "sender email",
"Password": "app password",
"EnableSSL": "true"
}
}
Upvotes: 0