我有一个ASP.NET MVC解决方案,并且在ASP.NET MVC项目中有大量HtmlHelper类,这些类获取数据并生成各种html片段以显示在各种页面上。
我现在必须运行一堆预定的工作,其中许多工作都会生成电子邮件。我将所有这些作业都移到了解决方案中的一个单独项目中(名为AdminJob.csproj),但现在我发现我必须生成许多具有与视图页面中的HTML非常相似的HTML的电子邮件。我正在努力避免管理作业依赖于ASP.NET MVC项目(因为如果需要,我希望将adminjob项目作为命令行运行),我还希望避免我的ASP.NET MVC项目依赖于adminjob项目(因为这看起来很奇怪)。
关于如何避免在ASP.NET MVC项目和AdminJob项目中重复相同的HTML呈现代码,有什么建议吗?
我唯一能想到的就是在解决方案中创建另一个名为"ViewHelpers"或类似的项目,并将我的所有HTMLHelpers移动到该项目中,这样我的MVC项目和AdminJob项目都可以引用它。为这段代码单独设计一个项目似乎有点过头了,但我想不出其他不会造成重复的解决方案。
有没有其他建议可以更好地做到这一点并避免任何重复?
我认为电子邮件是一种视图类型。我的网络应用程序中有几种视图类型(html、电子邮件、pdf、rss等)。这种模式有几个实现:在ruby on rails中的ActionMailer或其到asp.net的端口:MvcMailer。
这样,您就可以在web应用程序和电子邮件中充分利用Razor引擎,以减少重复。
您可以在另一个项目中承载视图,并通知ViewEngine在哪里查找视图(请参阅ASP.NET MVC中单独程序集中的视图)。我觉得这太夸张了。
另一种方法——我使用的方法——是将电子邮件模板与其他视图放在同一个项目中。
如果你想在网络应用程序之外呈现视图,你可以在控制台应用程序中使用以下工具之一编译剃刀模板:
- 剃刀模板:https://github.com/volkovku/RazorTemplates
- RazorEngine:https://github.com/Antaris/RazorEngine
- 使用MvcMailer之类的东西,您可以在计划任务中发出curl请求。MvcMailer需要一个HttpContext来运行,因此您将无法从控制台应用程序运行它。curl mvc操作会起作用
不要完全排除AdminJob依赖于网站的想法。这可能适用于您:如何在控制台应用程序中使用Razor视图引擎?。
请注意,对MVC项目具有编译时依赖关系的AdminJob不会而阻止AdminJob作为控制台应用程序运行。这可以很好地工作。
我预计的问题是——即使你把与View相关的东西转移到一个共享项目中——当你在网站之外运行时,你可能会发现它在运行时都会崩溃。在引擎盖下,存在对System.Web
的依赖关系,例如HttpContext
,它在运行时将为null。有些依赖项可以被存根,有些则不能。
在一个单独的共享项目中根本无法解决这个问题,所以我认为移动代码不会有任何好处。
但这里的典型方法(即我工作过的最后6家公司中有5家)是:
忘记命令行的想法吧。使管理工具成为网站的一部分。无论你想从命令行运行什么,都可以通过管理工具上的按钮运行。
PS
"与我的视图页面中的HTML非常相似的电子邮件"是一个你应该解决的问题。
它与视图页面相同,也可以与视图页面完全相同,在这种情况下,您希望AdminJob重用视图页面;或者它不是。在这种情况下,AdminJob应该有自己的HTML。在第二种情况下,假设不存在类似的HTML;如果不一样,那就不一样了。
我理解将常规网站页面中的html重用到电子邮件引擎中的诱惑。然而,我认为这是过度工程化的一个很好的例子。从长远来看,这将造成比短期利益更多的限制。
想想两件事:
电子邮件的HTML在设计上与网页的HTML不同。尽管今天他们看起来很相似,但明天他们看起来会不一样。你只是说——"用与我的视图页面中非常相似的HTML发送电子邮件",而不是说"用完全相同的HTML"。
用于电子邮件的HTML不应该有任何高级HTML或任何JavaScript。理想情况下,它应该有内联CSS,而不是JavaScript。与电子邮件客户端兼容的CSS非常有限。标记规则不同于为常规浏览器编写标记规则的自然和现代方式。一个很好的例子是电子邮件客户端对表格很友好,而在现代网络中,你现在很少使用表格,尤其是如果你想保持响应(跨屏幕平台浏览器)。点击此处了解所有限制:email-standards.org
现代网络的HTML不必像电子邮件那样静态。
这些都是流行的商业电子邮件发送者背后的想法。他们可以帮助您创建一个电子邮件分发列表,并在肩上生成适当的有限HTML。否则,它们会存在吗?如果没有标记差异,任何人都可以发送群电子邮件。
我从这一切得出的结论:如果你决定在电子邮件中使用你的网页标记,你就限制了两者。你在搞工程。如果你不在电子邮件中重复使用常规的页面标记,它会简单得多。我知道它们今天很相似,但明天可能不会。
显然,为您的电子邮件引擎提供模板功能是个好主意(与重用网页标记无关)。为此,您可以使用任何现有的模板引擎,也可以快速编写您的模板引擎(毕竟,如果您将HTML消息模板作为字符串从文件或数据库加载,脏字符串.Replace()将用值替换占位符)。
换句话说,要直接回答你的问题:不要犹豫,把网页和电子邮件这两条路分开。避免共享功能,因为它们大多不同。把这两者孤立起来考虑。