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

Posted

技术标签:

【中文标题】使用 C# 通过 Gmail SMTP 服务器发送电子邮件【英文标题】:Sending email through Gmail SMTP server with C# 【发布时间】:2022-01-09 07:14:54 【问题描述】:

由于某种原因,“Sending email in .NET through Gmail”的接受答案和任何其他答案都不适合我。为什么它们不起作用?

更新:我已经尝试了其他问题中的所有答案(已接受或不接受),但没有一个有效。

我只想知道它是否适用于其他人,否则谷歌可能已经改变了一些东西(以前发生过)。

当我尝试使用SmtpDeliveryMethod.Network 的代码时,我很快在Send(message) 上收到一个SmtpException。消息是

SMTP 服务器需要安全连接或客户端未通过身份验证。

服务器响应是:

5.5.1 需要身份验证。更多信息请访问“

更新:

这是我很久以前问过的一个问题,接受的答案是我在不同项目中多次使用过的代码。

我采用了这篇文章和其他 EmailSender 项目中的一些想法来创建一个EmailSender project at Codeplex。它专为可测试性而设计,并支持我最喜欢的 SMTP 服务,例如 GoDaddy 和 Gmail。

【问题讨论】:

我尝试使用不同语言的类似方法来做到这一点。遇到相同类型的事情:以前有效的旧文档方法对我不起作用。所以你会想知道谷歌是否改变了什么,或者你做错了什么。 @aaronls 最近唯一的变化似乎与 465 端口有关。我在寻找解决方案时尝试了它(我只是在做同样的工作),并且 465 端口一直超时。如果是这种情况,请尝试使用 587 端口。 这个问题是由于“文字验证”(验证码)造成的。如果您通过 Web 界面手动登录并填写验证码,您的 SMTP 将开始工作。 FWIW,为我工作。您需要使用 587 和 .EnableSSL true。 c# 4/.NET 4 当前不支持备用 465/SSL。 gmail 要求Configuring other mail clients。 关注@eglasius 的回答并确保在 Gmail 中打开“允许不太安全的应用程序”设置,以允许 gmail 对您的帐户进行身份验证。 【参考方案1】:

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

,这是必要的

【讨论】:

在 C# winforms 应用程序中为我出色地工作。谢谢,弗雷迪。 请记住,这样的代码实际上是以纯文本形式将您的 gmail 凭据传输给用户... web.config 中实际上有一个 enableSsl 的匹配设置,请看下面的答案 @Zidad 在 4.0 中添加。 您可能还需要在您的 gmail 设置页面中启用“不太安全的应用程序”的访问权限:google.com/settings/security/lesssecureapps。如果您收到异常“`服务器响应为:5.5.1 Authentication Required.【参考方案2】:

以下将几乎肯定是您的问题的答案如果所有其他方法都失败了

我得到了完全相同的错误,事实证明 Google 的新密码强度测量算法已经改变,认为我当前的密码太弱,并且没有告诉我有关它的任何事情(甚至没有消息或警告)......我发现这个?好吧,我选择更改我的密码,看看它是否有帮助(尝试了所有其他方法都无济于事),当我更改我的密码时,它起作用了!

然后,作为一个实验,我尝试将我的密码改回我以前的密码,看看会发生什么,Gmail 实际上并没有允许我这样做,理由是“对不起,我们不能让你保存这个更改因为您选择的密码太弱”并且不会让我回到我的旧密码。我从中发现它出错了,因为要么a)您需要每x个月更改一次密码,要么b)。正如我之前所说,他们的密码强度算法发生了变化,因此我的弱密码不被接受,即使他们在尝试登录 ANYWHERE 时没有说明任何内容!这种情况(第 2 种)是最有可能发生的情况,因为我的弱密码已经使用了大约 4 个月,它让我可以在 Gmail 中使用它。

他们对此只字未提,这很糟糕,但这是有道理的。因为大多数被劫持的电子邮件都是使用 gmail 之外的软件登录的,而且我猜如果你想在 Gmail 环境之外使用 Gmail,你需要有一个更强的密码。

【讨论】:

谢谢,正如您所说,请更改密码,使其强大且一切正常。 这正是我的问题 - 所有其他建议都是关于配置的,但我的配置从一开始就是正确的,但我不断收到错误。更改密码就大不一样了, 谢谢,我终于可以解决这个问题了,我的情况实际上更复杂,我可以从我的开发机器(位于乔治亚州,高加索)发送电子邮件,但电子邮件是生产服务器失败(英国)将密码更改为复杂密码后,现在一切正常:) 谢谢。我的 gmail 帐户也有同样的问题,它没有密码强度。我用强大的更新了它,我的代码正在运行。 谢谢,是的,最后只是将密码更改为强密码。【参考方案3】:

除了上述其他故障排除步骤之外,我还想补充一点,如果您在您的 GMail 帐户上启用了双因素身份验证(也称为two-step verification),您必须生成一个特定于应用程序的密码并使用新生成的密码通过 SMTP 进行身份验证

要创建一个,请访问:https://www.google.com/settings/ 并选择授权应用程序和站点以生成密码。

【讨论】:

我没有启用两步验证,我输入的密码有多安全也没关系,这是我解决问题的唯一方法。我能够使用其他 gmail 帐户,而无需两步和较弱的密码,没有任何问题...要使用我真正想使用的帐户,我必须启用两步并使用特定于应用程序的密码。 正是我在做什么,但仍然是同样的错误:-/ 好像我的密码不够强,但我使用的是 Gmail 给我的应用程序密码!!! 我没有看到任何这样的选项,也许分享那个链接?【参考方案4】:
Turn On Access For Less Secure Apps and it will work for all no need to change password.

Link to Gmail Setting

【讨论】:

这对我有用。更重要的是,当我尝试以上述方式发送电子邮件时,我实际上收到了来自 Google 的电子邮件,他们明确表示他们阻止了不太安全的应用程序的这种尝试,并提到了这种修复方法 这是谜题中最重要的关键,因为我设置了所有其他设置,但它似乎不起作用。一旦我开启了这个设置,它就像一个魅力。 这对我有用。应用密码 + SSL + NetworkCredentials。 (VB.NET)【参考方案5】:

我在从我的 gmail 帐户发送电子邮件时也遇到了一些问题,这是由于上述几种情况造成的。 以下是我如何使其工作并同时保持其灵活性的摘要:

首先设置您的 GMail 帐户: 启用 IMAP 并声明正确的最大消息数(you can do so here) 确保您的密码至少包含 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 属性的旧版应用程序。很棒的提示! 别忘了防火墙。端口 587 不是通常要打开的端口。【参考方案6】:

哦……太棒了…… 首先,由于任何原因,我无法发送电子邮件。 但是在我如下改变这两行的顺序后,它就完美了。

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

【讨论】:

是的,顺序不同。特别是当您设置属性凭据并且您不想使用默认凭据时。 根据文档,要使用凭据,您需要设置 UseDefaultCredentials = false。然而,这两个设置似乎暗中交织在一起。如果将 UseDefaultCredentials 设置为 true 或 false,则会产生将 Credentials 设置为 null 的副作用。并且似乎设置凭据可能会产生副作用设置 UseDefaultCredentials = false。虽然没有记录这样做,但可能是错误或只是一个蹩脚的开发人员。【参考方案7】:
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 需要身份验证。了解更多信息”之类的错误,因为我在此之前得到,请确保行 @ 987654322@ 包括在内,这一行应该在 SMTPClientObj.Credentials 之前。

我确实尝试以相反的方式切换这两行并返回 5.5.1 Authentication Required 错误

【讨论】:

这正是发生在我身上的事情。谁认为设置属性的顺序会修复/破坏事情! 这也是我的问题,我按照建议切换了顺序,效果很好 - 头疼,呃!【参考方案8】:

问题不在于通过 gmail 发送的技术能力之一。这适用于大多数情况。如果您无法让机器发送,这通常是由于机器没有通过控制人员至少一次的身份验证。

大多数用户面临的问题是 Google 决定一直更改出站限制。您应该始终将防御性代码添加到您的解决方案中。如果您开始看到错误,请降低发送速度并停止发送一段时间。如果您继续尝试发送,Google 有时会在您再次发送之前增加额外的延迟时间。

我在当前系统中所做的是在每条消息之间延迟 1.5 秒发送。然后,如果我遇到任何错误,请停止 5 分钟,然后重新开始。这通常有效,并且允许您发送到帐户的限制(上次我检查它是每天 2,000 次高级客户登录)。

【讨论】:

这正是我的问题!当我部署到生产环境时,我遇到了问题,当我在服务器上登录 Gmail 后,它又开始工作了。【参考方案9】:

解决此问题的简单步骤:

1)登录您的 Gmail

2)导航到此页面https://www.google.com/settings/security/lesssecureapps 并设置为“打开”

【讨论】:

【参考方案10】:

我遇到了同样的问题,但事实证明是我的病毒防护阻止了传出的“垃圾邮件”电子邮件。关闭它允许我使用端口 587 通过 GMail 发送 SMTP 电子邮件

【讨论】:

我禁用了 Windows Defender,它也开始工作了。【参考方案11】:

如果这里没有其他方法对您有用,您可能需要允许第三方应用程序访问您的 gmail 帐户。这是我的问题。要允许访问,请执行以下操作:

    登录您的 gmail 帐户。 访问此页面https://accounts.google.com/DisplayUnlockCaptcha 并单击按钮以允许访问。 访问此页面https://www.google.com/settings/security/lesssecureapps 并为不太安全的应用启用访问权限。

这对我有用,希望对其他人有用!

【讨论】:

为什么要还原我的编辑? Stack Overflow 试图通过在底部放置一张包含您的信息的卡片来保持网站清洁,无需签名或祝好运。 感谢您的理解!【参考方案12】:

我不确定这需要哪个 .NET 版本,因为 eglasius 提到没有匹配的 enableSsl 设置(我使用的是 .NET 4.0,但我怀疑它可以在 .NET 2.0 或更高版本中工作),但是这个配置对我有用(并且不需要您使用任何编程配置):

<system.net>
  <mailSettings>
    <smtp from="myusername@gmail.com" deliveryMethod="Network">
      <network defaultCredentials="false" enableSsl="true" host="smtp.gmail.com" port="587" password="password" userName="myusername@gmail.com"/>
    </smtp>
  </mailSettings>
</system.net>

您可能必须先在您的 Gmail 帐户上启用 POP 或 IMAP: https://mail.google.com/mail/?shva=1#settings/fwdandpop

我建议先用普通邮件客户端试试...

【讨论】:

这是 4.0 的新功能,比较版本 -> msdn.microsoft.com/en-us/library/ms164242(v=VS.90).aspx 嗨,Eglasius...好的,谢谢!奇怪的是,他们只有 4.0 之前的程序化方法。我想我们都会时不时忘记一些事情:)【参考方案13】:

@Andres Pompiglio:是的,您必须至少更改一次密码。 这段代码工作得很好:

//Satrt Send Email Function
public string SendMail(string toList, string from, string ccList,
    string subject, string body)


    MailMessage message = new MailMessage();
    SmtpClient smtpClient = new SmtpClient();
    string msg = string.Empty;
    try
    
        MailAddress fromAddress = new MailAddress(from);
        message.From = fromAddress;
        message.To.Add(toList);
        if (ccList != null && ccList != string.Empty)
            message.CC.Add(ccList);
        message.Subject = subject;
        message.IsBodyhtml = true;
        message.Body = body;
        // We use gmail as our smtp client
        smtpClient.Host = "smtp.gmail.com";   
        smtpClient.Port = 587;
        smtpClient.EnableSsl = true;
        smtpClient.UseDefaultCredentials = true;
        smtpClient.Credentials = new System.Net.NetworkCredential(
            "Your Gmail User Name", "Your Gmail Password");

        smtpClient.Send(message);
        msg = "Successful<BR>";
    
    catch (Exception ex)
    
        msg = ex.Message;
    
    return msg;

//End Send Email Function

您可以使用以下方法调用该函数:

Response.Write(SendMail(recipient Address, "UserName@gmail.com", "ccList if any", "subject", "body"))

【讨论】:

SMTP 服务器需要安全连接或客户端未通过身份验证。服务器响应为:5.5.1 需要身份验证。了解更多信息【参考方案14】:

我使用的是企业 *** 连接。这就是我无法从我的应用程序发送电子邮件的原因。如果我从 *** 断开连接,它就可以工作。

【讨论】:

【参考方案15】:

我遇到了同样的错误(“SMTP 服务器需要安全连接或客户端未通过身份验证。服务器响应为:5.5.1 需要身份验证。了解更多信息”)并找到出我使用了错误的密码。我修复了登录凭据,并且发送正确。

我知道这已经晚了,但也许这会对其他人有所帮助。

【讨论】:

【参考方案16】:

我还发现我用来登录的帐户由于某种原因被 google 停用了。一旦我重置了我的密码(和以前一样),我就可以发送电子邮件了。我也收到了 5.5.1 消息。

【讨论】:

【参考方案17】:

我也尝试了很多解决方案,但做了一些改变它会起作用

host = smtp.gmail.com
port = 587
username = email@gmail.com
password = password
enabledssl = true

使用 smtpclient 上面的参数可以在 gmail 中使用

【讨论】:

【参考方案18】:

我遇到了同样的错误,上述解决方案都没有帮助。

我的问题是我从远程服务器运行代码,该服务器从未用于登录 gmail 帐户。

我在远程服务器上打开了一个浏览器并从那里登录到 gmail。它询问了一个安全问题来验证它是我,因为这是一个新位置。完成安全检查后,我能够通过代码进行身份验证。

【讨论】:

【参考方案19】:

为您的帐户启用安全性较低的应用:https://www.google.com/settings/security/lesssecureapps

【讨论】:

【参考方案20】:
    首先检查您的 gmail 帐户设置并从“访问不太安全的应用程序”中打开

我们强烈建议您使用 Gmail 等安全应用来访问您的帐户。 Google 制作的所有应用都符合这些安全标准。另一方面,使用安全性较低的应用程序可能会使您的帐户容易受到攻击。了解更多。

    设置

    smtp.UseDefaultCredentials = false;
    

    之前

    smtp.Credentials = new NetworkCredential(fromAddress, fromPassword);
    

【讨论】:

这是在启用不太安全的访问后对我的应用程序的修复。谢谢【参考方案21】:

我发现的另一件事是您必须至少更改一次密码。 并尽量使用安全级别的密码(不要使用与密码相同的用户,123456等)

【讨论】:

【参考方案22】:

为您提供另一种可能的解决方案。我在通过 IMAP 连接到 gmail 时遇到了类似的问题。在尝试了我遇到的所有解决方案之后,您将在此处和其他地方阅读 SO(例如,启用 IMAP,启用对您的邮件的安全性较低的访问,使用https://accounts.google.com/b/0/displayunlockcaptcha 等等),我实际上设置了一个新的 gmail 帐户再一次。

在我最初的测试中,我创建的第一个 gmail 帐户已连接到我的主 gmail 帐户。这导致了谷歌引用错误帐户的不稳定行为。例如,运行https://accounts.google.com/b/0/displayunlockcaptcha 打开了我的主账户,而不是我为此目的创建的账户。

所以当我创建一个新帐户并且没有将其连接到我的主帐户时,按照上述所有适当的步骤进行操作后,我发现它工作正常!

我还没有证实这一点(即复制),但它显然是为我做的......希望它有所帮助。

【讨论】:

【参考方案23】:

这些错误有一个或多个原因。

在本地系统中使用您的 Gmail(或任何其他 if )登录。

还要检查不太安全的应用程序并将其设置为“打开”这里是 GMAIL 的链接。 https://www.google.com/settings/security/lesssecureapps

检查您的电子邮件代码中的 EnableSsl,并将其设置为 true。

smtp.EnableSsl = true;

还要检查您当前使用的端口。 25 是全球性的,但您也可以为其他人检查它,例如 587。 检查这里。 Does all SMTP communication happen over 25?

如果您处于远程状态:请检查上述 Vlad Tamas 的答案。

【讨论】:

如果我不想打开不太安全的应用程序设置怎么办,其他电子邮件客户端如何做到这一点,为什么我不能用 c# 做同样的事情?【参考方案24】:

您也可以通过端口 465 进行连接,但由于 System.Net.Mail 命名空间的一些限制,您可能必须更改您的代码。这是因为命名空间不提供建立隐式 SSL 连接的能力。这在http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx 进行了讨论,我在另一个讨论中提供了一个如何使用 CDO(协作数据对象)的示例 (GMail SMTP via C# .Net errors on all ports)。

【讨论】:

【参考方案25】:

我已经解决了这个问题。显然,该消息用于多种错误类型。 我的问题是我已达到最大 500 封已发送邮件。

登录帐户并手动尝试发送邮件。如果已达到限制,它将通知您

【讨论】:

【参考方案26】:

如果您的 Gmail 帐户已升级两步验证,则需要生成应用密码。 https://support.google.com/accounts/answer/185833?p=app_passwords_sa&hl=en&visit_id=636903322072234863-1319515789&rd=1 选择如何生成应用程序密码选项并按照提供的步骤操作。将生成的应用程序密码复制并粘贴到某处,因为单击完成后您将无法恢复它。

【讨论】:

【参考方案27】:
smtp.Host = "smtp.gmail.com"; //host name
smtp.Port = 587; //port number
smtp.EnableSsl = true; //whether your smtp server requires SSL
smtp.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
smtp.Credentials = new NetworkCredential(fromAddress, fromPassword);
smtp.Timeout = 20000;

【讨论】:

【参考方案28】:

更改您的 gmail 密码并重试,之后应该可以使用。

不知道为什么,但每次更改主机时都必须更改密码。

【讨论】:

【参考方案29】:

此代码适用于我,还允许从不安全的应用程序访问 gmail,并通过 2 个步骤删除身份验证:

Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(MailAddress, Password)

【讨论】:

以上是关于使用 C# 通过 Gmail SMTP 服务器发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Gmail SMTP 服务器在 C# 中发送邮件? [复制]

如何通过 Gmail 使用 C# 发送电子邮件

使用 gmail smtp 通过代理发送电子邮件

通过 GoDaddy 上的 gmail SMTP 发送电子邮件 [关闭]

使用gmail smtp c#发送电子邮件[重复]

发送 smtp gmail 电子邮件“发送邮件失败”