【发布时间】:2016-12-28 13:12:00
【问题描述】:
我需要以异步方式发送邮件。我已经想出使用 Razor Generator 从剃刀视图生成 Html 模板。现在我需要使用 SmtpClient.SendMailAsync 将 html 作为邮件发送。但我发现 Razor 生成器需要相当长的时间,我不想在我的发送邮件方法中包含模板生成部分,因为发送邮件方法不应该关心获取 Html 模板。
我有示例代码:
public static void SendEmailAsync<TModel>(TModel model, string templatePath, string subj, string toEmail, string cc = null, string bcc = null)
{
string templateFilePath = HostingEnvironment.MapPath(templatePath);
// Generate the email body from the template file.
// 'templateFilePath' should contain the absolute path of your template file.
if (templateFilePath != null)
{
Task.Run(() =>
{
var emailHtmlBody = Engine.Razor.RunCompile(File.ReadAllText(templateFilePath),
templateFilePath, model.GetType(), model);
SendEmailAsync(subj, emailHtmlBody, toEmail, cc, bcc);
});
}
else
{
throw new System.Exception("Could not find mail template.");
}
}
SendMailAsync 的签名是:
static async Task SendEmailAsync(string subj, string message, string toEmail, string cc = null, string bcc = null)
{
//Reading sender Email credential from web.config file
string fromEmail = ConfigurationManager.AppSettings["FromEmail"].ToString();
string fromName = ConfigurationManager.AppSettings["FromName"].ToString();
//creating the object of MailMessage
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress(fromEmail, fromName); //From Email Id
mailMessage.Subject = subj; //Subject of Email
mailMessage.Body = message; //body or message of Email
mailMessage.IsBodyHtml = true;
string[] toMuliId = toEmail.Split(',');
foreach (string toEMailId in toMuliId)
{
mailMessage.To.Add(new MailAddress(toEMailId)); //adding multiple TO Email Id
}
if (cc != null)
{
string[] ccId = cc.Split(',');
foreach (string ccEmail in ccId)
{
mailMessage.CC.Add(new MailAddress(ccEmail)); //Adding Multiple CC email Id
}
}
if (bcc != null)
{
string[] bccid = bcc.Split(',');
foreach (string bccEmailId in bccid)
{
mailMessage.Bcc.Add(new MailAddress(bccEmailId)); //Adding Multiple BCC email Id
}
}
SmtpClient smtp = new SmtpClient
{
EnableSsl = true,
Credentials = new NetworkCredential("", "")
};
//network and security related credentials
await smtp.SendMailAsync(mailMessage); //sending Email
}
没有抛出异常,但我得到了错误:
System.InvalidOperationException:此时无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行 Page 时发生此异常,请确保将 Page 标记为 。此异常还可能表示尝试调用“async void”方法,在 ASP.NET 请求处理中通常不支持该方法。相反,异步方法应该返回一个 Task,调用者应该等待它。
【问题讨论】:
-
基本问题似乎是您的
static void SendEmailAsync<TModel>(...)方法应该是static async Task SendEmailAsync<TModel>(...)。有了它,你可以awaitTask.Run()。这与之前提出的许多问题中讨论的问题完全相同,包括标记的重复项。 -
@PeterDuniho 我只是不想继续在我的所有方法中添加异步关键字,直到控制器。
-
@Aron 是的,谢谢,我认为这是同一个问题。
-
“我只是不想继续将 async 关键字添加到直到控制器的所有方法中” - 如果不这样做,您将无法正确使用
await。那么你接受的答案是如何解决你的问题的呢? -
@PeterDuniho 我只需要这一种方法发送邮件就可以在后台操作我只需要这一种方法。我只是不想把异步放在任何地方。所以使用 Task.run 我不必把异步放在我调用我的方法的任何地方。
标签: c# asp.net-mvc asynchronous async-await sendmail