使用C#通过Gmail SMTP服务器发送电子邮件

263
由于某些原因,对于“通过Gmail在.NET中发送电子邮件”,我既没有接受的答案也没有其他任何答案可用。为什么它们不起作用?
更新:我已经尝试了其他问题中的所有答案(被接受和其他),但它们都不起作用。
我只想知道它是否适用于其他人,否则Google可能已经改变了一些东西(这种情况以前发生过)。
当我尝试使用SmtpDeliveryMethod.Network的代码片段时,在Send(message)上很快收到SmtpException。消息是
SMTP服务器需要安全连接或客户端未经过身份验证。
服务器响应是:
5.5.1需要身份验证。在" <--真的,就到这里结束了。
更新:
这是我很久以前问的一个问题,接受的答案是我在不同项目中多次使用的代码。
我从本帖和其他EmailSender项目中汲取了一些思路,创建了一个Codeplex上的EmailSender项目。它专为可测试性而设计,并支持我最喜欢的SMTP服务,如GoDaddy和Gmail。

3
最近唯一的更改似乎与465端口有关。在寻找解决方案时,我尝试了它(我正在做同样的事情),但465端口总是超时。如果您遇到这种情况,请尝试使用587端口。 - eglasius
2
这个问题是由于“单词验证”(验证码)引起的。如果您手动通过Web界面登录并填写验证码,则SMTP将开始工作。 - Robert Koritnik
5
就我个人而言,这对我有效。你需要使用587端口和.EnableSSL true选项。目前,c#4/.NET4不支持备用的465/SSL端口。Gmail在配置其他邮件客户端方面有一些要求。 - gerryLowry
2
请遵循 @eglasius 的答案,并确保在 Gmail 中启用“允许不安全的应用程序”设置,以允许 Gmail 对您的帐户进行身份验证。 - user2713706
@eglasius 你好,我有一个问题,我想从发送者电子邮件函数发送电子邮件,它单独工作,但是当发送到用户的电子邮件时,其正文为空。我想知道是否可以通过gmail将ViewBag传递给发送电子邮件函数? - hasti.au
显示剩余3条评论
31个回答

314

CVertex,请确保检查您的代码,如果这样无法找到问题,请发布它。我刚刚在我正在开发的一个测试ASP.NET站点上启用了此项功能,并且它起作用。

实际上,在我的代码中曾经出现过问题。直到我在控制台程序上有了一个更简化的版本并看到它起作用后,我才发现它(没有改变Gmail方面的任何内容,正如您所担心的那样)。以下代码与您提到的示例完全相同:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new SmtpClient("smtp.gmail.com", 587)
            {
                Credentials = new NetworkCredential("myusername@gmail.com", "mypwd"),
                EnableSsl = true
            };
            client.Send("myusername@gmail.com", "myusername@gmail.com", "test", "testbody");
            Console.WriteLine("Sent");
            Console.ReadLine();
        }
    }
}

我也使用了web.config、http://msdn.microsoft.com/en-us/library/w355a94k.aspx以及代码的组合(因为配置文件中没有匹配的EnableSsl :( )来使它工作。

2021更新

默认情况下,您还需要在gmail设置页面中启用对“不安全应用程序”的访问:google.com/settings/security/lesssecureapps。如果出现异常“`服务器响应为:5.5.1需要身份验证”,则这是必要的。- 感谢@Ravendarksky


14
请记住,像这样的代码实际上会以明文形式向用户传输您的 Gmail 凭据。 - Chris Marisic
3
实际上,在web.config中有一个匹配的设置用于启用Ssl,请参见下面的答案。 - Wiebe Tijsma
4
@Zidad是在4.0版本中新增的。 - eglasius
28
您可能需要在Gmail设置页面中启用“较不安全的应用程序”访问权限: https://www.google.com/settings/security/lesssecureapps。如果您遇到异常错误信息 "The server response was: 5.5.1 Authentication Required.",则此步骤是必需的。请注意,启用此选项存在一定的安全风险,请谨慎操作。 - Ravendarksky
1
很遗憾,Gmail从今年开始不再允许“不安全的应用程序”。 - glitchwizard
显示剩余12条评论

78
除了上述其他故障排除步骤外,我还想补充一点,如果您已启用双重身份验证(也称为两步验证)在您的Gmail账户上,您必须生成应用专用密码,并使用新生成的密码通过SMTP进行身份验证
要创建一个应用专用密码,请访问:https://www.google.com/settings/并选择授权应用和站点以生成密码。

2
我之前并没有开启双重验证,无论我设置多么安全的密码也无济于事,这是我解决问题的唯一办法。我可以使用其他没有开启双重验证且密码较弱的Gmail账户而不会出现任何问题......但为了使用我真正想用的账户,我必须开启双重验证并使用应用程序专用密码。 - Ian Robertson
1
我正在做的正是这个,但还是出现了同样的错误 :-/ 它表现得好像我的密码不够强壮,但我正在使用 Gmail 给我的应用程序密码!!! - Jerry Dodge
我没有看到这样的选项,也许可以分享一下链接? - Web Developer
@Web开发人员:您必须先在您的账户上启用两步验证。只有这样您才被允许创建应用特定密码。[参考链接] (https://www.lifewire.com/get-a-password-to-access-gmail-by-pop-imap-2-1171882) - Himalaya Garg

76
以下内容几乎可以肯定是你的问题答案,如果其他方法都失败了:
我遇到了完全相同的错误,原来是谷歌新的密码强度测量算法已经改变,认为我的当前密码太弱,却没有告诉我任何信息(甚至没有提示或警告)。我是如何发现的呢?我选择更改密码以查看是否会有所帮助(尝试了所有其他方法都无效),当我更改密码时,它起作用了!然后,为了做个实验,我尝试将密码改回之前的那个,看看会发生什么,结果Gmail实际上不允许我这样做,给出了“很抱歉,我们无法允许您保存此更改,因为您选择的密码太弱”的原因,并且不允许我回到我的旧密码。从中我得出结论,这是错误的原因,要么是a) 您需要每隔X个月更改一次密码,要么是b) 正如我之前所说,他们的密码强度算法发生了变化,因此虽然他们在任何地方登录时都没有提醒我,但却不接受我使用的简单密码!这种情况(第2种)最有可能发生,因为我的弱密码已经有大约4个月的历史,而我仍然可以在Gmail中使用它。他们没有说明这一点是相当糟糕的,但也很合理。因为大多数被劫持的电子邮件都是使用Gmail外的软件登录的,如果您想在Gmail环境之外使用Gmail,则必须要有更强的密码。

3
谢谢,就像你说的那样,更改密码以使其更强大,一切都会正常工作。 - Gavin
2
这正是我的问题 - 所有其他建议都是关于配置的,但我的配置从一开始就是正确的,但我仍然不断收到错误。更改密码使一切都不同了。 - André Vermeulen
1
谢谢,最终我能够解决这个问题了, 我的情况实际上更加复杂, 我能够从我的开发机器(位于高加索的格鲁吉亚)发送电子邮件,但是从生产服务器(英国)发送电子邮件失败了。 更改密码为复杂密码后,现在一切都正常 :) - Kirill Chilingarashvili
1
谢谢。我也遇到了同样的问题,我的 Gmail 账户没有密码强度。我更新了一个强密码,现在我的代码可以正常工作了。 - Thomas.Benz
1
谢谢,是的,最终只需要将密码更改为强密码即可。 - Misha Beskin
1
谢谢。更改我的Gmail密码解决了问题。但问题不是更安全的密码,我只是需要更改它。看起来每次更改我的主机都需要这样做。 - Jo Smo

59
打开“允许不安全应用程序访问”功能,即可让所有应用程序正常工作,无需更改密码。 Gmail 设置链接

1
这对我很有效。更重要的是,当我尝试以上述方式发送电子邮件时,我实际上收到了来自Google的电子邮件,在那里他们明确表示阻止了来自不安全应用程序的此尝试,并提到了这种解决方法。 - Demarsch
1
这是拼图中最重要的关键,因为我已经设置好了其他所有设置,但似乎它并没有起作用。一旦我打开了这个设置,它就像魔法般地工作了。 - Lost
1
这对我有用。应用程序密码+SSL+网络凭据。(VB.NET) - CrazyIvan1974
3
此设置已不再可用。了解更多 - Himalaya Garg

32

我也曾经在使用我的Gmail账户发送邮件时遇到了一些问题,这些问题有几个是上述情况引起的。以下是我如何使其工作并保持灵活性的总结:

  • 首先设置您的GMail帐户:
    • 启用IMAP并确认最大消息数量正确(可以在此处完成)
    • 确保您的密码至少为7个字符,并且足够强壮(根据Google)
    • 确保您不必先输入验证码。您可以通过从浏览器发送测试电子邮件来实现。
  • 在web.config中进行更改(或者app.config,我还没有尝试过,但我认为在Windows应用程序中使其工作同样容易):
<configuration>
    <appSettings>
        <add key="EnableSSLOnMail" value="True"/>   
    </appSettings>

    <!-- other settings --> 

    ...

    <!-- system.net settings -->
    <system.net>
        <mailSettings>
            <smtp from="yourusername@gmail.com" deliveryMethod="Network">
                <network 
                    defaultCredentials="false" 
                    host="smtp.gmail.com" 
                    port="587" 
                    password="stR0ngPassW0rd" 
                    userName="yourusername@gmail.com"
                    />
                <!-- When using .Net 4.0 (or later) add attribute: enableSsl="true" and you're all set-->
            </smtp>
        </mailSettings>
    </system.net>
</configuration>
Add a Class to your project:

Imports System.Net.Mail

Public Class SSLMail

    Public Shared Sub SendMail(ByVal e As System.Web.UI.WebControls.MailMessageEventArgs)

        GetSmtpClient.Send(e.Message)

        'Since the message is sent here, set cancel=true so the original SmtpClient will not try to send the message too:
        e.Cancel = True

    End Sub

    Public Shared Sub SendMail(ByVal Msg As MailMessage)
        GetSmtpClient.Send(Msg)
    End Sub

    Public Shared Function GetSmtpClient() As SmtpClient

        Dim smtp As New Net.Mail.SmtpClient
        'Read EnableSSL setting from web.config
        smtp.EnableSsl = CBool(ConfigurationManager.AppSettings("EnableSSLOnMail"))
        Return smtp
    End Function

End Class

现在,每当您想要发送电子邮件,您只需要调用 SSLMail.SendMail

例如,在一个带有 PasswordRecovery 控件的页面中:

Partial Class RecoverPassword
Inherits System.Web.UI.Page

Protected Sub RecoverPwd_SendingMail(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MailMessageEventArgs) Handles RecoverPwd.SendingMail
    e.Message.Bcc.Add("webmaster@example.com")
    SSLMail.SendMail(e)
End Sub

End Class

或者在您的代码中的任何位置调用:

SSLMail.SendMail(New system.Net.Mail.MailMessage("from@from.com","to@to.com", "Subject", "Body"})

希望这篇文章能帮助到遇到这个问题的任何人!(我使用的是VB.NET,但我认为将其转换为任何.NET语言都是微不足道的。)


+1 "enableSsl="true" - 这对于一个遗留应用程序非常有效,该应用程序没有特别设置Smtp.enableSsl属性而不重新编译程序集。非常好的提示! - Metro Smurf
请确保防火墙设置正确。端口587不是常用的开放端口。 - Guy Lowe

15

哦……太神奇了!起初,我因为某些原因无法发送电子邮件。但是在我按照以下方式调整这两行代码的顺序后,它完美地运行了。

//(1)
client.UseDefaultCredentials = true;
//(2)
client.Credentials = new System.Net.NetworkCredential("username@gmail.com", "password");

1
是的,顺序很重要。特别是当您设置凭据属性并且不想使用默认凭据时。 - Stefan Cvetanovski
1
根据文档,要使用凭据,您需要将UseDefaultCredentials设置为false。然而,这两个设置似乎是秘密交织在一起的。如果您将UseDefaultCredentials设置为true或false,它将具有将Credentials设置为null的副作用。而且,似乎设置凭据可能会副作用地将UseDefaultCredentials设置为false。虽然没有记录为这样做,但可能是错误或只是一个糟糕的开发人员。 - Aaron

13
Dim SMTPClientObj As New Net.Mail.SmtpClient
SMTPClientObj.UseDefaultCredentials = False
SMTPClientObj.Credentials = New System.Net.NetworkCredential("myusername@gmail.com", "mypwd")
SMTPClientObj.Host = "smtp.gmail.com"
SMTPClientObj.Port = 587
SMTPClientObj.EnableSsl = True
SMTPClientObj.Send("myusername@gmail.com","yourusername@gmail.com","test","testbody")
如果你遇到类似于“SMTP服务器需要安全连接或客户端未经过身份验证。服务器响应为:5.5.1 需要身份验证。”的错误,确保在 SMTPClientObj.Credentials 之前包含以下代码行 SMTPClientObj.UseDefaultCredentials = False
我曾试图反转这两行代码的位置,结果出现了“5.5.1 需要身份验证”错误。

这正是发生在我身上的事情。谁会想到设置属性的顺序会修复/破坏事物! - Bill Yang
这也是我的问题,我按照建议改变了顺序,现在它正常工作了 - 真让人头疼! - eth0

12

问题并不在于通过Gmail发送邮件的技术能力,对于大多数情况,它都可以正常工作。如果您无法让机器发送邮件,通常是因为该机器尚未被人类控制过进行过身份验证。

大多数用户面临的问题是,谷歌公司时常更改外发限制。您应该始终为您的解决方案添加防御性代码。如果您开始看到错误,请减慢发送速度,暂停发送一段时间。如果您一直尝试发送,谷歌有时会在您可以再次发送之前增加额外的延迟时间。

在我的当前系统中,我设置了每个邮件之间1.5秒的延迟时间进行发送。然后,如果我收到任何错误,就会停止5分钟,然后重新开始发送。这通常有效,并可以允许您发送达到帐户限制(上次我检查时,Premier客户每天登录的限制为2,000封邮件)。


2
这正是我的问题!当我部署到生产环境时,出现了这个问题。在我登录服务器上的Gmail后,它又开始正常工作了。 - ThisGuy

11

11

我曾经遇到过同样的问题,但是后来发现是我的病毒防护软件屏蔽了外发的“垃圾邮件”。关闭该功能后,我就能够使用587端口通过Gmail发送SMTP邮件了。


1
我禁用了Windows Defender,然后它开始工作了。 - MorioBoncz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接