private void SendMailCallback(IAsyncResult result) { try { _writer = _transport.EndSendMail(result); // If some recipients failed but not others, send the e-mail anyway, but then return the // "Non-fatal" exception reporting the failures. The sync code path does it this way. // Fatal exceptions would have thrown above at transport.EndSendMail(...) SendMailAsyncResult sendResult = (SendMailAsyncResult)result; // Save these and throw them later in SendMessageCallback, after the message has sent. _failedRecipientException = sendResult.GetFailedRecipientException(); } catch (Exception e) { Complete(e, result); return; } try { if (_cancelled) { Complete(null, result); } else { _message !.BeginSend(_writer, DeliveryMethod != SmtpDeliveryMethod.Network, IsUnicodeSupported(), new AsyncCallback(SendMessageCallback), result.AsyncState !); } } catch (Exception e) { Complete(e, result); } }
public SmtpFailedRecipientsException(string?message, Exception?innerException) : base(message, innerException) { SmtpFailedRecipientException?smtpException = innerException as SmtpFailedRecipientException; _innerExceptions = smtpException == null?Array.Empty <SmtpFailedRecipientException>() : new SmtpFailedRecipientException[] { smtpException }; }
internal MailWriter SendMail(MailAddress sender, MailAddressCollection recipients, string deliveryNotify, bool allowUnicode, out SmtpFailedRecipientException?exception) { if (sender == null) { throw new ArgumentNullException(nameof(sender)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } MailCommand.Send(_connection !, SmtpCommands.Mail, sender, allowUnicode); _failedRecipientExceptions.Clear(); exception = null; string response; foreach (MailAddress address in recipients) { string smtpAddress = address.GetSmtpAddress(allowUnicode); string to = smtpAddress + (_connection !.DSNEnabled ? deliveryNotify : string.Empty); if (!RecipientCommand.Send(_connection, to, out response)) { _failedRecipientExceptions.Add( new SmtpFailedRecipientException(_connection.Reader !.StatusCode, smtpAddress, response)); } } if (_failedRecipientExceptions.Count > 0) { if (_failedRecipientExceptions.Count == 1) { exception = _failedRecipientExceptions[0]; } else { exception = new SmtpFailedRecipientsException(_failedRecipientExceptions, _failedRecipientExceptions.Count == recipients.Count); } if (_failedRecipientExceptions.Count == recipients.Count) { exception.fatal = true; throw exception; } } DataCommand.Send(_connection !); return(new MailWriter(_connection !.GetClosableStream(), encodeForTransport: true)); }
public void Send(MailMessage message) { ObjectDisposedException.ThrowIf(_disposed, this); if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(this, $"DeliveryMethod={DeliveryMethod}"); NetEventSource.Associate(this, message); } SmtpFailedRecipientException?recipientException = null; if (InCall) { throw new InvalidOperationException(SR.net_inasync); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (DeliveryMethod == SmtpDeliveryMethod.Network) { CheckHostAndPort(); } MailAddressCollection recipients = new MailAddressCollection(); if (message.From == null) { throw new InvalidOperationException(SR.SmtpFromRequired); } if (message.To != null) { foreach (MailAddress address in message.To) { recipients.Add(address); } } if (message.Bcc != null) { foreach (MailAddress address in message.Bcc) { recipients.Add(address); } } if (message.CC != null) { foreach (MailAddress address in message.CC) { recipients.Add(address); } } if (recipients.Count == 0) { throw new InvalidOperationException(SR.SmtpRecipientRequired); } _transport.IdentityRequired = false; // everything completes on the same thread. try { InCall = true; _timedOut = false; _timer = new Timer(new TimerCallback(TimeOutCallback), null, Timeout, Timeout); bool allowUnicode = false; string?pickupDirectory = PickupDirectoryLocation; MailWriter writer; switch (DeliveryMethod) { case SmtpDeliveryMethod.PickupDirectoryFromIis: throw new NotSupportedException(SR.SmtpGetIisPickupDirectoryNotSupported); case SmtpDeliveryMethod.SpecifiedPickupDirectory: if (EnableSsl) { throw new SmtpException(SR.SmtpPickupDirectoryDoesnotSupportSsl); } allowUnicode = IsUnicodeSupported(); // Determined by the DeliveryFormat parameter ValidateUnicodeRequirement(message, recipients, allowUnicode); writer = GetFileMailWriter(pickupDirectory); break; case SmtpDeliveryMethod.Network: default: GetConnection(); // Detected during GetConnection(), restrictable using the DeliveryFormat parameter allowUnicode = IsUnicodeSupported(); ValidateUnicodeRequirement(message, recipients, allowUnicode); writer = _transport.SendMail(message.Sender ?? message.From, recipients, message.BuildDeliveryStatusNotificationString(), allowUnicode, out recipientException); break; } _message = message; message.Send(writer, DeliveryMethod != SmtpDeliveryMethod.Network, allowUnicode); writer.Close(); //throw if we couldn't send to any of the recipients if (DeliveryMethod == SmtpDeliveryMethod.Network && recipientException != null) { throw recipientException; } } catch (Exception e) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Error(this, e); } if (e is SmtpFailedRecipientException && !((SmtpFailedRecipientException)e).fatal) { throw; } Abort(); if (_timedOut) { throw new SmtpException(SR.net_timeout); } if (e is SecurityException || e is AuthenticationException || e is SmtpException) { throw; } throw new SmtpException(SR.SmtpSendMailFailure, e); } finally { InCall = false; if (_timer != null) { _timer.Dispose(); } } }