it-swarm-tr.com

Gmail ile SmtpClient

Bir okul projesi için posta istemcisi geliştiriyorum. C # içindeki SmtpClient komutunu kullanarak e-posta göndermeyi başardım. Bu, herhangi bir sunucuyla mükemmel çalışır, ancak Gmail ile çalışmaz. TLS kullanan Google yüzünden olduğuna inanıyorum. EnableSsl üzerinde true ayarını SmtpClient olarak ayarlamayı denedim, ancak bu bir fark yaratmıyor.

Bu, SmtpClient dosyasını oluşturmak ve bir e-posta göndermek için kullandığım kod.

this.client = new SmtpClient("smtp.gmail.com", 587);
this.client.EnableSsl = true;
this.client.UseDefaultCredentials = false;
this.client.Credentials = new NetworkCredential("username", "password");

try
{
    // Create instance of message
    MailMessage message = new MailMessage();

    // Add receiver
    message.To.Add("[email protected]");

    // Set sender
    // In this case the same as the username
    message.From = new MailAddress("[email protected]");

    // Set subject
    message.Subject = "Test";

    // Set body of message
    message.Body = "En test besked";

    // Send the message
    this.client.Send(message);

    // Clean up
    message = null;
}
catch (Exception e)
{
    Console.WriteLine("Could not send e-mail. Exception caught: " + e);
}

Bir e-posta göndermeye çalıştığımda alıyorum hatadır.

Could not send e-mail. Exception caught: System.Net.Mail.SmtpException: Message could not be sent. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateNotAvailable, RemoteCertificateChainErrors
  at System.Net.Mail.SmtpClient.<callback>m__4 (System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) [0x00000] in <filename unknown>:0 
  at System.Net.Security.SslStream+<BeginAuthenticateAsClient>c__AnonStorey7.<>m__A (System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Int32[] certErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.OnRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslStreamBase.RaiseRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.RaiseServerCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] certificateErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
  at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0 
  at P2Mailclient.SMTPClient.send (P2Mailclient.Email email) [0x00089] in /path/to/my/project/SMTPClient.cs:57 

Bu hatayı neden aldığım konusunda bir fikri olan var mı?

30
simonbs

Bunu çalıştırmayı deneyin:

mozroots --import --ask-remove

sisteminizde (yalnızca bash'ta veya Windows'ta ise Mono Komut İstemi'nden) Sonra kodu tekrar çalıştırın.

DÜZENLE:

Ben de seni kaçmalıyım unuttum

certmgr -ssl smtps://smtp.gmail.com:465

(ve sorulara evet cevabı). Bu benim için Mono 2.10.8, Linux'ta çalışıyor (sizin örneğinizle).

22

Gmail’in SMTP sunucusu, isteğinizi geçerli bir gmail e-posta/şifre kombinasyonu ile doğrulamanızı gerektirir. SSL’nin de etkinleştirilmesi gerekir. Gerçekte, tüm değişkenlerinizin bir dökümünü, yapabileceğimin en iyi tahmininde geçirilemeden, Kimlik bilgilerinizin geçersiz olduğu, geçerli bir kullandığınızdan emin olun GMAIL'DE e-posta/şifre kombinasyonu.

Çalışan bir örnek için here komutunu okumak isteyebilirsiniz.

EDIT: Tamam, işte o zaman yazdığım ve test ettiğim bir şey ve benim için iyi çalıştı:

public static bool SendGmail(string subject, string content, string[] recipients, string from) {
    if (recipients == null || recipients.Length == 0)
        throw new ArgumentException("recipients");

    var gmailClient = new System.Net.Mail.SmtpClient {
        Host = "smtp.gmail.com",
        Port = 587,
        EnableSsl = true,
        UseDefaultCredentials = false,
        Credentials = new System.Net.NetworkCredential("******", "*****")
    };

    using (var msg = new System.Net.Mail.MailMessage(from, recipients[0], subject, content)) {
        for (int i = 1; i < recipients.Length; i++)
            msg.To.Add(recipients[i]);

        try {
            gmailClient.Send(msg);
            return true;
        }
        catch (Exception) {
            // TODO: Handle the exception
            return false;
        }
    }
}

Daha fazla bilgiye ihtiyacınız olursa, benzer bir SO makalesi burada

23
Jason Larke

SSL bağlantılarını kurmak için kullanılan sunucu sertifikasını doğrulamanız gerektiğini düşünüyorum.

Sunucu sertifikasını doğrulayarak posta göndermek için aşağıdaki kodu kullanın.

            this.client = new SmtpClient(_account.SmtpHost, _account.SmtpPort);
            this.client.EnableSsl = _account.SmtpUseSSL;
            this.client.Credentials = new NetworkCredential(_account.Username, _account.Password);

        try
        {
            // Create instance of message
            MailMessage message = new MailMessage();

            // Add receivers
            for (int i = 0; i < email.Receivers.Count; i++)
                message.To.Add(email.Receivers[i]);

            // Set sender
            message.From = new MailAddress(email.Sender);

            // Set subject
            message.Subject = email.Subject;

            // Send e-mail in HTML
            message.IsBodyHtml = email.IsBodyHtml;

            // Set body of message
            message.Body = email.Message;

            //validate the certificate
            ServicePointManager.ServerCertificateValidationCallback =
            delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            { return true; };


            // Send the message
            this.client.Send(message);

            // Clean up
            message = null;
        }
        catch (Exception e)
        {
            Console.WriteLine("Could not send e-mail. Exception caught: " + e);
        }

ServicePointManager işlevini kullanmak için System.Security.Cryptography.X509Certificates ad alanını içe aktarın

4
user1082916

Bu kod benim için iyi çalışıyor, bunu LinqPad'e yapıştırmayı deneyin, posta adreslerini ve şifreyi düzenleyin ve bize ne gördüğünüzü söyleyin:

var client = new System.Net.Mail.SmtpClient("smtp.gmail.com", 587);
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("[email protected]", "xxxxxxx");

try
{
    // Create instance of message
    System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();

    // Add receiver
    message.To.Add("[email protected]");

    // Set sender
    // In this case the same as the username
    message.From = new System.Net.Mail.MailAddress("[email protected]");

    // Set subject
    message.Subject = "Test";

    // Set body of message
    message.Body = "En test besked";

    // Send the message
    client.Send(message);

    // Clean up
    message = null;
}
catch (Exception e)
{
    Console.WriteLine("Could not send e-mail. Exception caught: " + e);
}
3
rasmusvhansen

Gmail hesabınızda 2 Adımlı Doğrulamayı etkinleştirmeniz ve bir uygulama şifresi oluşturmanız gerekir ( https://support.google.com/accounts/answer/185833?hl=tr ). Şifrenizi yeni uygulama şifresiyle değiştirdikten sonra, çalışması gerekir.

Credentials = new System.Net.NetworkCredential("your email address", "your app password");
3
Poet

Bunu 6 Mayıs için çalıştıktan sonra Mayıs 2013'te GMail ile almaya başladım. Mono projesinin Güvenilir Köklerini Saygıyla Kullanma belgesinde çalışma konusunda rehberlik sağlandı. Seçenek 1'i seçtim:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Hizmetimin uyarı vermeden çalışmasını durdurmak için e-posta adresimin olması çok rahatsız edici.

26 Ağustos 2016 Güncellemesi: kullanıcı Chico, ServerCertificateValidationCallback geri çağırma işleminin aşağıdaki tamamlanmasını önerdi. Test etmedim.

ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;

bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
    bool isOk = true;
    // If there are errors in the certificate chain, look at each error to determine the cause.
    if (sslPolicyErrors != SslPolicyErrors.None) {
        for (int i=0; i<chain.ChainStatus.Length; i++) {
            if (chain.ChainStatus [i].Status != X509ChainStatusFlags.RevocationStatusUnknown) {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0);
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                bool chainIsValid = chain.Build ((X509Certificate2)certificate);
                if (!chainIsValid) {
                    isOk = false;
                }
            }
        }
    }
    return isOk;

}
1
t9mike