Ejemplo n.º 1
0
        internal IAsyncResult BeginSendMail(MailAddress sender, MailAddressCollection recipients,
                                            string deliveryNotify, bool allowUnicode, AsyncCallback callback, object state)
        {
            if (sender == null)
            {
                throw new ArgumentNullException(nameof(sender));
            }

            if (recipients == null)
            {
                throw new ArgumentNullException(nameof(recipients));
            }

            SendMailAsyncResult result = new SendMailAsyncResult(_connection, sender, recipients,
                                                                 allowUnicode, _connection.DSNEnabled ? deliveryNotify : null,
                                                                 callback, state);

            result.Send();
            return(result);
        }
Ejemplo n.º 2
0
        public void SendAsync(MailMessage message, object userToken)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this, message, userToken, _transport);
            }

            try
            {
                if (InCall)
                {
                    throw new InvalidOperationException(Strings.net_inasync);
                }

                if (message == null)
                {
                    throw new ArgumentNullException(nameof(message));
                }

                if (DeliveryMethod == SmtpDeliveryMethod.Network)
                {
                    CheckHostAndPort();
                }

                _recipients = new MailAddressCollection();

                if (message.From == null)
                {
                    throw new InvalidOperationException(Strings.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(Strings.SmtpRecipientRequired);
                }

                try
                {
                    InCall     = true;
                    _cancelled = false;
                    _message   = message;
                    string pickupDirectory = PickupDirectoryLocation;

                    CredentialCache cache;
                    // Skip token capturing if no credentials are used or they don't include a default one.
                    // Also do capture the token if ICredential is not of CredentialCache type so we don't know what the exact credential response will be.
                    _transport.IdentityRequired = Credentials != null && (ReferenceEquals(Credentials, CredentialCache.DefaultNetworkCredentials) || (cache = Credentials as CredentialCache) == null || IsSystemNetworkCredentialInCache(cache));

                    _asyncOp = AsyncOperationManager.CreateOperation(userToken);
                    switch (DeliveryMethod)
                    {
                    case SmtpDeliveryMethod.PickupDirectoryFromIis:
                        throw new NotSupportedException(Strings.SmtpGetIisPickupDirectoryNotSupported);

                    case SmtpDeliveryMethod.SpecifiedPickupDirectory:
                    {
                        if (EnableSsl)
                        {
                            throw new SmtpException(Strings.SmtpPickupDirectoryDoesnotSupportSsl);
                        }

                        _writer = GetFileMailWriter(pickupDirectory);
                        bool allowUnicode = IsUnicodeSupported();
                        ValidateUnicodeRequirement(message, _recipients, allowUnicode);
                        message.Send(_writer, true, allowUnicode);

                        if (_writer != null)
                        {
                            _writer.Close();
                        }

                        _transport.ReleaseConnection();
                        AsyncCompletedEventArgs eventArgs = new AsyncCompletedEventArgs(null, false, _asyncOp.UserSuppliedState);
                        InCall = false;
                        _asyncOp.PostOperationCompleted(_onSendCompletedDelegate, eventArgs);
                        break;
                    }

                    case SmtpDeliveryMethod.Network:
                    default:
                        _operationCompletedResult = new ContextAwareResult(_transport.IdentityRequired, true, null, this, s_contextSafeCompleteCallback);
                        lock (_operationCompletedResult.StartPostingAsyncOp())
                        {
                            if (NetEventSource.IsEnabled)
                            {
                                NetEventSource.Info(this, $"Calling BeginConnect. Transport: {_transport}");
                            }
                            _transport.BeginGetConnection(_operationCompletedResult, ConnectCallback, _operationCompletedResult, Host, Port);
                            _operationCompletedResult.FinishPostingAsyncOp();
                        }
                        break;
                    }
                }
                catch (Exception e)
                {
                    InCall = false;

                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, e);
                    }

                    if (e is SmtpFailedRecipientException && !((SmtpFailedRecipientException)e).fatal)
                    {
                        throw;
                    }

                    Abort();
                    if (_timedOut)
                    {
                        throw new SmtpException(Strings.net_timeout);
                    }

                    if (e is SecurityException ||
                        e is AuthenticationException ||
                        e is SmtpException)
                    {
                        throw;
                    }

                    throw new SmtpException(Strings.SmtpSendMailFailure, e);
                }
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Send a message via SMTP, optionally, bypass the RCPT TO recipients with the added rcpto collection.
        /// Otherwise, default behavior is to send to all recipients listed in To, Cc, and Bcc.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="rcptToRecipients"></param>
        public void Send(MailMessage message, IEnumerable <MailAddress> rcptToRecipients = null)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this, message);
            }

            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            try
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"DeliveryMethod={DeliveryMethod}");
                    NetEventSource.Associate(this, message);
                }

                SmtpFailedRecipientException recipientException = null;

                if (InCall)
                {
                    throw new InvalidOperationException(Strings.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(Strings.SmtpFromRequired);
                }

                var rcptTo = (rcptToRecipients ?? Enumerable.Empty <MailAddress>()).ToArray();

                if (rcptTo.Length > 0)
                {
                    foreach (var i in rcptTo)
                    {
                        recipients.Add(i);
                    }
                }
                else
                {
                    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(Strings.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(Strings.SmtpGetIisPickupDirectoryNotSupported);

                    case SmtpDeliveryMethod.SpecifiedPickupDirectory:
                        if (EnableSsl)
                        {
                            throw new SmtpException(Strings.SmtpPickupDirectoryDoesnotSupportSsl);
                        }

                        allowUnicode = IsUnicodeSupported();     // Determend by the DeliveryFormat paramiter
                        ValidateUnicodeRequirement(message, recipients, allowUnicode);
                        writer = GetFileMailWriter(pickupDirectory);
                        break;

                    case SmtpDeliveryMethod.Network:
                    default:
                        GetConnection();
                        // Detected durring GetConnection(), restrictable using the DeliveryFormat paramiter
                        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();
                    _transport.ReleaseConnection();

                    //throw if we couldn't send to any of the recipients
                    if (DeliveryMethod == SmtpDeliveryMethod.Network && recipientException != null)
                    {
                        throw recipientException;
                    }
                }
                catch (Exception e)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, e);
                    }

                    if (e is SmtpFailedRecipientException && !((SmtpFailedRecipientException)e).fatal)
                    {
                        throw;
                    }

                    Abort();
                    if (_timedOut)
                    {
                        throw new SmtpException(Strings.net_timeout);
                    }

                    if (e is SecurityException ||
                        e is AuthenticationException ||
                        e is SmtpException)
                    {
                        throw;
                    }

                    throw new SmtpException(Strings.SmtpSendMailFailure, e);
                }
                finally
                {
                    InCall = false;
                    if (_timer != null)
                    {
                        _timer.Dispose();
                    }
                }
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
            }
        }