【问题标题】:Where should I put shared HTML generation code in an ASP.NET MVC project?我应该将共享的 HTML 生成代码放在 ASP.NET MVC 项目中的什么位置?
【发布时间】:2017-01-17 00:45:54
【问题描述】:

我有一个 ASP.NET MVC 解决方案,并且我在 ASP.NET MVC 项目中有大量 HtmlHelper 类,它们获取数据并生成各种 html 的 sn-ps 以显示在各种页面上。

我现在必须运行一堆预定的作业,其中许多作业会生成电子邮件。我将所有这些工作转移到解决方案中的一个单独项目(称为 AdminJob.csproj)中,但现在我发现我必须生成许多具有与我在视图页面中非常相似的 HTML 的电子邮件。我试图让管理作业不依赖于 ASP.NET MVC 项目(因为如果需要,我想将 adminjob 项目作为命令行运行),并且我还想避免拥有我的 ASP.NET MVC 项目依赖于 AdminJob 项目(因为这看起来很奇怪)。

关于如何避免在我的 ASP.NET MVC 项目和我的 AdminJob 项目中重复相同的 HTML 呈现代码的任何建议?

我唯一能想到的就是在解决方案中创建另一个名为“ViewHelpers”或类似的项目,并将我的所有 HTMLHelpers 移动到该项目中,以便我的 MVC 项目和 AdminJob 项目都可以引用它。为这段代码创建一个单独的项目似乎有点矫枉过正,但我​​想不出另一种不会产生重复的解决方案。

对于更好的方法来做到这一点并避免任何重复,还有其他建议吗?

【问题讨论】:

  • 您的建议似乎合乎逻辑。然而,这个问题主要是基于意见的,将被解释为离题。
  • 我不同意这完全是基于意见的,因为我在这里寻找最佳实践,这似乎是一种常见的情况,您同时拥有 MVC 视图和具有重叠要求的电子邮件生成,所以我认为有证据考虑到关注点和其他目标的分离,以及基于主体的答案。有什么建议可以改变问题中的某些内容以使您认为它不会离题吗?
  • 我会按照你的建议去做,为共享代码创建一个单独的项目。但是不要将它创建为“SharedHTML”或类似的东西,最终会显示更多应该共享的代码,您可以使用这个项目来完成所有这些。
  • 可能是另一种选择(如果您不想共享视图)是从电子邮件实用程序对 mvc 操作进行 http 调用以获取 html。
  • 您的 HTML 是否嵌入在您的代码中?

标签: asp.net-mvc html-email html-helper


【解决方案1】:

我的看法是电子邮件是一种视图类型。我的网络应用程序中有几种视图类型(html、电子邮件、pdf、rss 等)。这种模式有多种实现方式:ActionMailer 在 ruby​​ on rails 或它到 asp.net 的端口中:MvcMailer

这样,您可以在 Web 应用程序和电子邮件中充分利用 Razor 引擎,以减少重复。

您可以在另一个项目中托管您的视图,并通知您的 ViewEngine 在哪里查找视图(请参阅Views in separate assemblies in ASP.NET MVC)。我觉得这有点矫枉过正。

另一种方式——我使用的方式——是将电子邮件模板与其他视图放在同一个项目中。

如果您想在 Web 应用程序之外呈现视图,您可以使用以下之一在控制台应用程序中编译剃须刀模板:

【讨论】:

    【解决方案2】:

    不要完全排除让 AdminJob 依赖于网站的想法。这可能对您有用:How to use Razor View Engine in a console application?

    请注意,对 MVC 项目具有编译时依赖性的 AdminJob 确实不会阻止 AdminJob 作为控制台应用程序运行。这可以正常工作。

    我预计的问题是——即使你将与视图相关的东西移到一个共享项目中——你可能会发现在网站之外运行时它会在运行时中断。在引擎盖下,有对 System.Web 东西的依赖,例如HttpContext,在运行时将为空。有些依赖项可以被存根,有些则不能。

    在一个单独的共享项目中根本不会解决这个问题,所以我不认为移动代码有什么好处。

    但这里的典型方法(即我工作过的最后 6 家公司中有 5 家)是:

    忘记命令行的想法。使管理工具成为网站的一部分。无论您想从命令行运行什么,都可以通过管理工具上的按钮运行它。

    PS

    “与我的视图页面中的 HTML 非常相似的电子邮件”是一个你应该解决的问题。

    它与视图页面相同,在这种情况下,您希望 AdminJob 重用视图页面;或者不是。在这种情况下,AdminJob 应该有自己的 HTML。在第二种情况下,采取没有“相似”HTML之类的说法;如果不一样,那就不一样了。

    【讨论】:

      【解决方案3】:

      我理解将常规网站页面中的 html 重用于您的电子邮件引擎的诱惑。但是,我认为这是过度设计的一个很好的例子。与短期收益相比,这将产生更多的长期限制。

      想想几件事:

      用于电子邮件的 HTML 在设计上不同于用于页面的 HTML。即使今天它们看起来相似,明天它们也会看起来不同。您刚刚说过 - '电子邮件与我在我的视图页面中的 HTML 非常相似',你没有说'具有完全相同的 HTML'。

      电子邮件的 HTML 中不应包含任何高级 HTML 或任何 JavaScript。理想情况下,它应该有内联 CSS 而没有 JavaScript。与电子邮件客户端兼容的 CSS 非常有限。标记规则不同于为常规浏览器编写它的自然和现代方式。一个很好的例子是电子邮件客户端对表格很友好,而在现代网络中你现在很少使用表格,特别是如果你想保持响应(跨屏幕平台浏览器)。在此处阅读所有限制:email-standards.org

      现代网络的 HTML 不必像电子邮件消息那样静态。

      所有这些原因都是流行的在线商业电子邮件发件人背后的想法。他们帮助您创建一个电子邮件分发列表,并且他们不厌其烦地在他们的肩膀上生成适当的有限 HTML。否则,它们会存在吗?如果不是标记差异,任何人都可以发送群组电子邮件。

      我的结论:如果您决定对电子邮件使用网页标记,那么您就是在限制两者。你过度设计了。如果您不将常规页面标记重用到您的电子邮件中,它会简单得多。我知道它们今天很相似,但明天可能就不一样了。

      显然,为您的电子邮件引擎提供模板功能是个好主意(与重用网页标记无关)。为此,您可以使用任何现有的模板引擎,或者您可以快速编写自己的引擎(毕竟,如果您将 HTML 消息模板作为字符串,从文件或数据库加载,脏 string.Replace() 将用值替换占位符)。

      换句话说,直接回答您的问题:不要犹豫,将网页和电子邮件这两条路径分开。避免共享功能,因为它们大多不同。将两者分开考虑。

      【讨论】:

        猜你喜欢
        • 2011-08-27
        • 2020-04-24
        • 1970-01-01
        • 1970-01-01
        • 2011-10-01
        • 2011-09-29
        • 2011-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多