【问题标题】:UserManager SendEmailAsync No Email SentUserManager SendEmailAsync 未发送电子邮件
【发布时间】:2015-07-20 18:00:39
【问题描述】:

我正在使用以下代码尝试异步发送电子邮件,但没有发送电子邮件,并且我不确定哪些操作不正确。我还在 web.config 中为电子邮件协议添加了第二段代码。

SendEmailAsync 代码

await UserManager.SendEmailAsync(username.Id, "MTSS-B: Forgot Password", "Here is your new password. Please go back to the MTSS-B web tool and sign in. You will be prompted to create your own password.<br/><br/>" + tmpPass + "<br/><br/>MTSS-B Administrator");

Web.config 代码

<system.net>
<mailSettings>
  <smtp>
    <network host="smtp1.airws.org" userName="" password="" />
  </smtp>
</mailSettings>
</system.net>

****更新****

我测试了是否可以使用常规方法发送电子邮件,并且可以使用以下代码发送电子邮件。

MailMessage m = new MailMessage(new MailAddress(ConfigurationManager.AppSettings["SupportEmailAddr"]), new MailAddress(model.Email));
m.Subject = "MTSS-B: Forgot Password"; 
m.Body = string.Format("Here is your new password. Please go back to the MTSS-B web tool and sign in. You will be prompted to create your own password.<br/><br/>Password: " + tmpPass + "<br/><br/>MTSS-B Administrator"); 
m.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient("smtp2.airws.org"); 
smtp.Send(m);

【问题讨论】:

  • 您需要在web.config文件中有一个有效的用户名和密码
  • 我们不需要用户名和密码来访问我们的网络主机。这已在其他应用程序中以相同的方式实现。
  • 你有端口号吗?如果端口号不是问题,请尝试使用非异步 SendEmail 功能来测试它是否出错。
  • 好的,我试试非异步发送邮件功能。
  • 我可以使用 system.net.mail 发送电子邮件,所以我不确定为什么我无法使用 sendemailasync 发送电子邮件。

标签: c# asp.net-mvc


【解决方案1】:

在您的应用中,您可能在App_Start 文件夹中有一个名为IdentityConfig.cs 的文件。该文件的顶部可能是这样的:

public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // Plug in your email service here to send an email.
        return Task.FromResult(0);
    }
}

改成:

public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        SmtpClient client = new SmtpClient();
        return client.SendMailAsync(ConfigurationManager.AppSettings["SupportEmailAddr"], 
                                    message.Destination, 
                                    message.Subject, 
                                    message.Body);
    }
}

根据自己的喜好自定义发送代码。

【讨论】:

  • 我没有机会测试这个解决方案,但如果我再次遇到问题会尝试。谢谢!
  • 完美。谢谢。
  • 对我来说是 EmailService.cs
  • ConfigurationManager.AppSettings["key"]ConfigurationManager.AppSettings.Get("key")有区别吗?
【解决方案2】:

Joe 的解决方案给了我很多指导,谢谢! 然而,要使用它,您必须包含以下命名空间:

using System.Configuration;
using System.Net.Mail;

我已经稍微改变了他的解决方案,经过大量尝试后,我找到了一些有效的代码(它仍然必须重新设计,但它不会改变想法),这就是我的 SendAsync 方法的样子:

public Task SendAsync(IdentityMessage message) {
    //SmtpClient client = new SmtpClient();
    //return client.SendMailAsync(ConfigurationManager.AppSettings["SupportEmailAddr"],
    //                            message.Destination,
    //                            message.Subject,
    //                            message.Body);

    SmtpClient client = new SmtpClient();
    client.Port = 587;
    client.Host = "smtp.gmail.com";
    client.EnableSsl = true;
    //client.Timeout = 10000;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false;
    client.Credentials = new NetworkCredential("mailName@gmail.com", "mailPassword");

    return client.SendMailAsync("mailName@gmail.com", message.Destination, message.Subject, message.Body);
}

您可以在顶部看到 Joe 的解决方案的注释,然后,对 SmtpClient 进行了很多配置(由于我一直在进行一些测试,对超时进行了注释,如果它适合您的需要,您可以取消注释)。

之后,邮件以异步方式发送,请注意发件人(Joe 从 AppSettings 变量中获取)与凭据中指定的相同(您必须创建一个 gmail [或您想要的任何邮件服务] 帐户并使用它的名称和密码来创建凭据)。

这应该可以解决问题!请记住,在尝试以这种方式连接到您的新邮件帐户时,gmail 可能会使您的生活复杂化,要解决它,您必须登录该帐户并转到your account configurations 并激活“不太安全的应用程序访问”(或类似的东西) ,我会说西班牙语,所以我的翻译可能不太好......)。

编辑 22/04/16:似乎此解决方案在代理工作时无法正常工作,应该有一种配置方法。就我而言,我发现禁用代理并继续运行会更便宜,但对于那些负担不起的人来说,希望在实施时遇到这个障碍。

【讨论】:

  • 你能解释一下你在代理问题方面做了什么吗?当我从本地计算机运行通过 gmail 的解决方案时,它运行良好,但是当我将代码发布到 Azure 时,我得到 502 - Web 服务器在充当网关或代理服务器时收到无效响应。 我我想知道这是否与您的问题有关。谢谢!
  • 恐怕不是,我们在我的工作中有一个代理,这是一个麻烦,我最终在它启动时从未收到邮件,直到我禁用它测试,但问题都在发布到天蓝色之前。可悲的是,我不记得在部署时遇到过 azure 的问题。 [链接]stackoverflow.com/questions/21135784/…那家伙好像也有同样的问题,显然是在连接字符串上。我建议你从那里开始:/
  • 感谢您回复我!将检查链接。
【解决方案3】:

我认为您正在使用Macrosoft ASP.NET Identity 和 SMTP 电子邮件客户端服务器。那么你的完整配置如下:

Web.config

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

创建一个类 SmtpEmailService.cs

public class SmtpEmailService : IIdentityMessageService
{
    readonly ConcurrentQueue<SmtpClient> _clients = new ConcurrentQueue<SmtpClient>();

    public async Task SendAsync(IdentityMessage message)
    {
        var client = GetOrCreateSmtpClient();
        try
        {
            MailMessage mailMessage = new MailMessage();

            mailMessage.To.Add(new MailAddress(message.Destination));
            mailMessage.Subject = message.Subject;
            mailMessage.Body = message.Body;

            mailMessage.BodyEncoding = Encoding.UTF8;
            mailMessage.SubjectEncoding = Encoding.UTF8;
            mailMessage.IsBodyHtml = true;

            // there can only ever be one-1 concurrent call to SendMailAsync
            await client.SendMailAsync(mailMessage);
        }
        finally
        {
            _clients.Enqueue(client);
        }
    }


    private SmtpClient GetOrCreateSmtpClient()
    {
        SmtpClient client = null;
        if (_clients.TryDequeue(out client))
        {
            return client;
        }

        client = new SmtpClient();
        return client;
    }
}

IdentityConfig.cs

// Configure the application user manager used in this application. 
//UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<User>
{
    public ApplicationUserManager(IUserStore<User> store, IIdentityMessageService emailService)
        : base(store)
    {
        this.EmailService = emailService;
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<User>(context.Get<ApplicationDbContext>()), new SmtpEmailService());
        .
        .
        .
        .
        return manager;
    }
}

如果您使用依赖注入 (DI),请对其进行配置。我正在使用 UnityContainer (UnityConfig.cs),所以我的配置是:

container.RegisterType<IIdentityMessageService, SmtpEmailService>();

最后从你的控制器中使用它:

public async Task<IHttpActionResult> TestSmtpMail()
{
    var subject = "Your subject";
    var body = "Your email body it can be html also";
    var user = await UserManager.FindByEmailAsync("xxx@gmail.com");
    await UserManager.SendEmailAsync(user.Id, subject, body);
    return Ok();
}

你可能会得到类似的错误:

SMTP 服务器需要安全连接,或者客户端没有 已通过身份验证。

然后Allow less security apps & Allow gmail account making it possible for other apps to gain access

更多详情和SendGrid客户请访问here

【讨论】:

    【解决方案4】:

    太好了。谢谢你。我有错误,因为ConfigurationManager.AppSettings["SupportEmailAddr"] 为空。您必须在 web.config 文件中设置它。 你有一个部分叫做:&lt;appSettings&gt;. 这也是 ConfigurationManager.AppSettings 所指的。 ["SupportEmailAddr"] 正在查看名为 SupportEmailAddr 的特定设置。 在您的 web.config 中,它看起来像这样:

    <appSettings>
        <add key="SupportEmailAddr" value="someone@example.com" />
    </appSettings>
    

    【讨论】:

      【解决方案5】:

      使用 VS2017 的开箱即用构建,带有 Web 表单和个人帐户的 C# Web 应用程序,我发现这条评论帮助我解决了从 ConfigurationManager.AppSettings 调用返回的 NULL 值。

      我确认邮件设置都是正确的,但我无法通过调用 ConfigurationManager 来检索字符串值获得有效结果。它总是返回 NULL。

      我发现,如果您在解决方案资源管理器树中使用应用程序设置(项目名称 -> 属性 -> Settings.Settings),您将始终返回 NULL,因为 Web.Config 文件中的部分将不存在,但是该部分具有不同的语法。

      请记住将部分放在最后的结束标记之前。

      简单而优雅,感谢 Goran。

      【讨论】:

        猜你喜欢
        • 2020-06-02
        • 2014-10-26
        • 2020-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-18
        • 1970-01-01
        相关资源
        最近更新 更多