【问题标题】:What would be considered the best way to architect sending email from a C# web application?从 C# Web 应用程序发送电子邮件的最佳架构方式是什么?
【发布时间】:2011-12-19 00:41:06
【问题描述】:

我正在开发一个即将上线的 Web 应用程序,我现在正试图找出处理从该应用程序发送电子邮件的最佳方法。我完全了解如何使用 MailMessage 和 SmtpClient 类从应用程序发送电子邮件,但是我的问题来自不同的角度。在这个项目之前,我工作的主要目的是支持在我之前开发的旧应用程序。在这些应用程序中,当他们需要发送电子邮件时,他们会将任何消息硬编码到实际消息中,并将所有 HTML 标记直接嵌入到 C# 代码中。

我正在开发的应用程序将有一个用于发送电子邮件的模板,作为一种样式容器,并且不同的消息将嵌入到模板的主要内容 div 中。我想避免在这个应用程序中对这些模板进行硬编码,所以我一直在尝试找出布局我的项目的最佳方式。我曾想过使用 t4 模板,并将不同的 t4 读入应用程序,并应用具有指定参数的 String.Format 以将名称/电子邮件添加到要发送的消息中。但是,我不确定这是不是最好的方法。

我的另一个想法是为每种类型的消息定义一个类,但这最终会再次硬编码消息,正如我所说的我不想这样做。

我的问题是,您过去是如何处理这个问题的?什么有效,什么无效,出于什么原因?我在网上查遍了所有内容,但要么只有关于如何发送消息的内容,要么我没有使用正确的 Google 强力词。

【问题讨论】:

  • 到目前为止,关于聊天代码,您自己尝试过什么,以便在线的人可以看到并可能帮助您..?取决于您真正在寻找什么发送电子邮件不是一项艰巨的任务,因为.NET 为您提供了许多使用 System.Net.Mail 或通过 Web 应用程序使用 System.Web.Mail 的选项,还有很多以前的示例你可以在这个网站上搜索和研究,或者查看 codeproject.com 很多很好的例子
  • 主要是所有的代码都在我的脑海中。在我花大量时间编写代码之前,我想先了解一下最好的方法。我已经尝试研究这个几个小时了。我不需要手牵手怎么做,只需要知道应该做什么。到目前为止我提出的想法都在我的问题中,但正如我所说,我不确定这是解决问题的最佳方法。
  • 您可以访问数据库吗?您可以将每种类型的消息、收件人、主题、正文等存储在数据库中,并在此基础上构建一个简单的维护例程。您还可以在电子邮件正文中输入各种标签以充当其他文本(如用户名)的占位符。我以前做过,效果还不错。
  • 应用程序确实有一个数据库,这是我实际上考虑过的事情之一。起初我对这样做有点谨慎,因为我不确定消息是否应该存储在数据库中,但是可以随时更新消息绝对是一个专业人士。收件人当前也存储在数据库中。感谢您的意见,既然我知道其他人做得很好,我肯定会更多地考虑它。我仍然想知道是否有更好的方法。

标签: c# asp.net-mvc email architecture t4


【解决方案1】:

我是这样做的:

  • 使用 ViewModel 和 Razor 模板以通常的方式对其进行编码
  • 通过创建电子邮件,使用http://razorengine.codeplex.com/ 加载和解析模板
  • 如果您想在线程中发送电子邮件,请注意不要使用 Html 和 Url 助手,因为它们依赖于您在这种情况下没有的 HttpContext。如果需要,构建您自己的助手。

例如,如果您的应用程序中有一个 ViewModel Car 显示在某处,您也可以将此 ViewModel 用作 Razor 模板中的@model 用于电子邮件。

【讨论】:

  • 感谢您的链接。这在某种程度上肯定更接近我正在寻找的东西。假设您将模板作为一个实际的单独文件,我是否正确,或者您是否按照它们在主页上显示的方式对其进行硬编码?
  • 当然没有硬编码,对于每封电子邮件,我都有一个 cshtml 文件。因此,您也可以将其用作应用程序中的电子邮件预览。
  • 嗯.. 能够预览消息无疑是一个加分项。我非常喜欢这个功能的想法。
  • 你可以看看 MvcMailer 已经建好的地方。但我认为你可能无法在一个线程中发送邮件。
  • 我曾考虑过这个,但对使用它持谨慎态度,因为我将从应用程序的服务端发送电子邮件,而不是 Web 应用程序端本身。该站点最终将在 Windows Azure 上运行,因此我想尽量减少服务和网站之间的电子邮件\用户信息的来回传递以进行发送。这是将电子邮件存储在数据库中听起来不错的原因之一 - 更新应用程序可能是一个漫长的过程。
【解决方案2】:

我不得不这样做几次。我最初使用基于我认为 Rick Strahl 博客文章的 ASP.Net 模板引擎。它奏效了,但我总是遇到一些问题。

我转而使用NVelocity 模板引擎,发现它是一种非常简单的创建和维护电子邮件模板的方法。还有许多其他模板引擎,我怀疑下次我可能会认真看看Razorengine

将值合并到模板中的代码:

private string Merge(ManualTypeEnum manualType, Object mergeValues)
{
    var body = "";
    var templateFile = string.Format("{0}MailTemplate.vm", manualType);
    var velocity = new VelocityEngine();
    var props = new ExtendedProperties();
    props.AddProperty("file.resource.loader.path", Config.EmailTemplatePath);
    velocity.Init(props);
    var template = velocity.GetTemplate(templateFile);
    var context = new VelocityContext();
    context.Put("Change", mergeValues);
    using (var writer = new StringWriter())
    {
        template.Merge(context, writer);
        body = writer.ToString();
    }
    return body;
}

要合并的值作为匿名对象传递,并且可以包括各种类型,包括列表等,例如

var emailBody = Merge(newDocument.ManualType, new
{
    ManualType = newDocument.ManualType.ToString(),
    Message = change.Message,
    NewTitle = newDocument.Title ?? "",
    NewVersion = newDocument.Version ?? "",
    Contact = From,
    Changes = change.ToList(),
});

【讨论】:

  • 嗯.. 看起来我可以用文件来做到这一点,但我可能会考虑将 Razor 引擎与数据库结合起来,从数据行中获取信息,然后对其进行转换。关注点分离呢?你认为这会使它们混合太多吗?
  • 一切都与上下文有关。使用上述代码的应用程序在我使用它时已经过时且笨拙,并且使用数据库来存储模板对于正在发送的电子邮件的数量/复杂性来说太过分了。考虑模板只是一个字符串,然后您可以将该字符串存储在文件或数据库中,这对您的应用程序有意义。使用 Razor 模板的好处之一是 Visual Studio 支持,因此您将获得语法着色等。如果您将它们存储在数据库中,则每当您想要修改它们时,您都会添加几个额外的步骤,即提取、更改、更新。
  • 非常正确。但是,在我的情况下,将其存储在数据库中可能最终会更容易。我当然可以将文件放在我的电脑上,并在需要时通过代码更新数据库。将更改部署到 azure 需要很长时间,而且我会犹豫是否只为这样的小更改而重新部署。
猜你喜欢
  • 2013-01-06
  • 1970-01-01
  • 2010-11-14
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
相关资源
最近更新 更多