|
-
Thread Starter
PowerPoster
[RESOLVED] C# application getting error using SMTP for one user who got a new computer
There is a function in my application where a user creates an Excel file and sends it as an attachment to a group email, let's call it [email protected], using SMTP. A user who has always been able to do this successfully until yesterday is getting this exception. I wrote this block of code yesterday to catch SmtpFailedRecipientsException when I was getting a very general exception "Unable to send to all recipients". This message is not much better. It says Failed Recipient: <[email protected]> Status Code: Mailbox unavailable.
Code:
// 06/22/26 - Code from google search of "c# SmtpClient message unable to send to all recipients".
catch (SmtpFailedRecipientsException ex)
{
// Loops through only the specific recipients that failed
foreach (SmtpFailedRecipientException innerEx in ex.InnerExceptions)
{
//Console.WriteLine($"Failed recipient: {innerEx.FailedRecipient}");
//Console.WriteLine($"SMTP Status Code: {innerEx.StatusCode}");
MessageBox.Show(String.Format("Failed Recipient: {0} Status Code: {1}", innerEx.FailedRecipient, innerEx.StatusCode));
}
}
The mailbox should not be unavailable. Another user sent it fine. So I don't think it's my code, I think it's the user's "new computer". Does anybody know of something that needs to be set up/configured to be able to do this? What about the new computer is relevant: OS, programs installed, etc.? I think I can fix the problem by taking the 5 or so people who are in the group and adding them one at a time to the MailMessage.To list, but that won't really help us know what this problem is and I would like to know that. Thank you for any insight.
There are 10 kinds of people in this world. Those who understand binary, and those who don't.
-
Re: C# application getting error using SMTP for one user who got a new computer
There are a few things that this could be. Are you manually setting up credentials or are you using default credentials? Also, does the SMTP server have an IP address whitelist? If so, then the new machine's IP could have changed, and the whitelist simply needs to be updated.
Bottom line, I doubt that this is a code issue. This appears to be a much more frustrating issue: networking related.
-
Thread Starter
PowerPoster
Re: C# application getting error using SMTP for one user who got a new computer
Thanks for the reply. Re: credentials, here is the complete code block. I believe if you don't say explicitly, then UseDefaultCredentials is true.
We will look into whitelist. That came up previously. (By AI, but I trust you more LOL).
Code:
using (MailMessage message = new MailMessage())
{
using (SmtpClient smtp = new SmtpClient())
{
try
{
message.From = new MailAddress("[email protected]");
message.To.Add(new MailAddress(Globals.Variables.SpecialHandlingEmail)); // This is the email group of 5 or so peeps
message.CC.Add(new MailAddress(emp.EmailAddress));
message.Subject = emailSubject;
message.IsBodyHtml = true; // true or false, whether we want to make message body html or plain text
message.Body = emailBody;
if (fileName != "")
{
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment(fileName);
message.Attachments.Add(attachment);
}
smtp.Port = 25;
smtp.Host = "XXX.outlook.com";
smtp.EnableSsl = true;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Send(message);
}
// 06/22/26 - Code from google search of "c# SmtpClient message unable to send to all recipients".
catch (SmtpFailedRecipientsException ex)
{
// Loops through only the specific recipients that failed
foreach (SmtpFailedRecipientException innerEx in ex.InnerExceptions)
{
//Console.WriteLine($"Failed recipient: {innerEx.FailedRecipient}");
//Console.WriteLine($"SMTP Status Code: {innerEx.StatusCode}");
MessageBox.Show(String.Format("Failed Recipient: {0} Status Code: {1}", innerEx.FailedRecipient, innerEx.StatusCode));
}
}
// 06/22/26 - This was my general error handler that has been here all along. I added the caption so we know that yes it is CMS giving this error, but really CMS is passing it along from SMTP.
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
MessageBox.Show(ex.Message, "CMS 2.0 Unknown SMTP Error");
return false;
}
}
}
There are 10 kinds of people in this world. Those who understand binary, and those who don't.
-
Thread Starter
PowerPoster
Re: C# application getting error using SMTP for one user who got a new computer
Ugh. I just wrote a whole reply and my token had expired so it went poof ?
So again, this is not an issue anymore. We have a way that remote users are supposed to log in and run my application off a server. Per our network engineer, "Our internal mail connector will only accept messages originating from the office". The user with the problem was using RDP directly and running my app locally. I didn't think to ask, I assumed she was following the rules and concentrated on the "new computer" part of her story. She's all set now and I've learned to ask the obvious up front.
There are 10 kinds of people in this world. Those who understand binary, and those who don't.
-
Re: [RESOLVED] C# application getting error using SMTP for one user who got a new com
Are you using an older version of the Outlook SMTP? The reason I ask is because I'm not familiar with port 25, typically it's port 587. Take a look at this table (SMTP is towards the bottom): https://support.microsoft.com/en-us/...or-outlook-com
You're already turning on EnableSsl, which is correct. However, the way I've done it in the past is to use port 587.
By the way, you could pass many of the variables in the various class constructors to save on some lines of code, though this is a style preference. Also, I'd probably recommend implementing an interface for this. You might not need it now, but it greatly simplifies the process if you ever needed to switch from Outlook to something else.
Try this for instance (untested, but should give you an idea):
Code:
public interface ISmtpEmailer
{
public int Port { get; }
public string Server { get; }
public Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo);
public Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo, string emailCC);
public Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo, string emailCC, string emailBCC);
public Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo);
public Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo, IEnumerable<string> emailsCC);
public Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo, IEnumerable<string> emailsCC, IEnumerable<string> emailsBCC);
}
public class OutlookEmailer : ISmtpEmailer
{
public int Port { get => 587; }
public string Server { get => "smtp.outlook.com"; }
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo)
{
await SendAsync(subject, body, attachment, emailFrom, [ emailTo ]);
}
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo, string emailCC)
{
await SendAsync(subject, body, attachment, emailFrom, [ emailTo ], [ emailCC ]);
}
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, string emailTo, string emailCC, string emailBCC)
{
await SendAsync(subject, body, attachment, emailFrom, [ emailTo ], [ emailCC ], [ emailBCC ]);
}
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo)
{
await SendAsync(subject, body, attachment, emailFrom, emailsTo, []);
}
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo, IEnumerable<string> emailsCC)
{
await SendAsync(subject, body, attachment, emailFrom, emailsTo, emailsCC, []);
}
public async Task SendAsync(string subject, string body, string attachment, string emailFrom, IEnumerable<string> emailsTo, IEnumerable<string> emailsCC, IEnumerable<string> emailsBCC)
{
// require subject
if (string.IsNullOrWhiteSpace(subject))
{
throw new ArgumentOutOfRangeException(nameof(subject));
}
// require body
if (string.IsNullOrWhiteSpace(body))
{
throw new ArgumentOutOfRangeException(nameof(body));
}
// require email from
if (string.IsNullOrWhiteSpace(emailFrom))
{
throw new ArgumentOutOfRangeException(nameof(emailFrom));
}
// require email to
if (!emailsTo.Any())
{
throw new ArgumentOutOfRangeException(nameof(emailsTo), $"{nameof(emailsTo)} cannot be empty.");
}
ParseEmailAddresses(emailsTo);
var mailAddressesTo = string.Join(",", emailsTo);
using (MailMessage message = new MailMessage(emailFrom, mailAddressesTo, subject, body))
using (SmtpClient smtp = new SmtpClient(Server, Port))
{
// get any optional CCs
if (emailsCC.Any())
{
var parsedCCEmails = ParseEmailAddresses(emailsCC);
foreach (var parsedEmail in parsedCCEmails)
{
message.CC.Add(parsedEmail);
}
}
// get any optional BCCs
if (emailsBCC.Any())
{
var parsedBCCEmails = ParseEmailAddresses(emailsBCC);
foreach (var parsedEmail in parsedBCCEmails)
{
message.Bcc.Add(parsedEmail);
}
}
// set remaining email options
message.IsBodyHtml = true;
if (!string.IsNullOrWhiteSpace(attachment))
{
var emailAttachment = new Attachment(attachment);
message.Attachments.Add(emailAttachment);
}
// set SMTP options
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.EnableSsl = true;
smtp.UseDefaultCredentials = true;
// send baby, send!
await smtp.SendMailAsync(message);
}
}
private static MailAddressCollection ParseEmailAddresses(IEnumerable<string> emailAddresses)
{
var emailCollection = new MailAddressCollection();
var invalidEmails = new List<string>();
foreach (var email in emailAddresses)
{
if (!MailAddress.TryCreate(email, out var parsedMailAddress))
{
invalidEmails.Add(email);
}
else
{
emailCollection.Add(parsedMailAddress);
}
}
if (invalidEmails.Any())
{
var joinedEmails = string.Join(", ", invalidEmails);
throw new FormatException($"The following email addresses are invalid: {joinedEmails}");
}
return emailCollection;
}
}
Unusable Demo (because of limitations): https://dotnetfiddle.net/5RSRpc
-
Re: C# application getting error using SMTP for one user who got a new computer
 Originally Posted by MMock
I didn't think to ask, I assumed she was following the rules and concentrated on the "new computer" part of her story. She's all set now and I've learned to ask the obvious up front.
Oh man, it's even worse than a networking issue. It's a human issue!!!
-
Thread Starter
PowerPoster
Re: [RESOLVED] C# application getting error using SMTP for one user who got a new com
OK, the 587 vs 25 difference is interesting. Because when I was originally developing this 5 years ago, I didn't right away have the info needed to work with our internal outlook mail server. So to keep going, I temporarily used a gmail account. (I don't remember this all very well but knowing that I don't remember, I made a lot of notes!) When it was gmail, I used Port = 587 and Host = "smtp.gmail.com". But then I guess our engineer told me to use Port 25 and what our host name was. And it's been that way since.
There are 10 kinds of people in this world. Those who understand binary, and those who don't.
-
Re: [RESOLVED] C# application getting error using SMTP for one user who got a new com
Based on what you're describing, it sounds like you're actually using SMTP Relay. Check out this documentation: https://learn.microsoft.com/en-us/ex...-or-office-365
The reason for this guess is because it uses port 25 and requires one or more static IP addresses to be authenticated based on the "Our internal mail connector will only accept messages originating from the office" quote.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|