我有一个ASP.NET MVC解决方案,我在ASP.NET MVC项目中有大量的HtmlHelper类,它们获取数据并生成各种html片段以显示在各个页面上。
我现在必须运行一系列预定作业,其中许多作业会生成电子邮件。我将所有这些工作都移到了解决方案中的一个单独的项目中(称为AdminJob.csproj),但我现在发现我必须生成一些与我在视图页面中具有非常相似的HTML的电子邮件。我试图让管理工作不依赖于ASP.NET MVC项目(因为我希望在需要时将adminjob项目作为命令行运行),我也想避免使用我的ASP.NET MVC项目依赖于AdminJob项目(因为这看起来很奇怪)。
有关如何避免在我的ASP.NET MVC项目和AdminJob项目中复制相同HTML呈现代码的任何建议?
我唯一能想到的是在解决方案中创建另一个名为“ViewHelpers”的项目或类似的东西,并将我的所有HTMLHelpers移动到该项目中,以便我的MVC项目和AdminJob项目都可以引用它。为这段代码创建一个单独的项目似乎有点过头了,但我想不出另一个不会造成重复的解决方案。
有什么其他建议可以更好地实现此目的并避免重复吗?
答案 0 :(得分:6)
我看待这个的方式是电子邮件是一种视图类型。我的网络应用程序中有几种视图类型(html,email,pdf,rss等)。这种模式有几种实现:轨道上的ruby中的ActionMailer或者asp.net的端口:MvcMailer。
通过这种方式,您可以在Web应用程序和电子邮件中充分利用Razor引擎,以减少重复。
您可以在另一个项目中托管您的视图,并通知您的ViewEngine查看视图的位置(请参阅Views in separate assemblies in ASP.NET MVC)。我发现这有点矫枉过正。
另一种方式 - 我使用的方法 - 将电子邮件模板与其他视图放在同一个项目中。
如果要在Web应用程序之外渲染视图,可以使用以下方法之一在控制台应用程序中编译剃刀模板:
答案 1 :(得分:1)
不要完全排除让AdminJob依赖网站的想法。这可能适合您:How to use Razor View Engine in a console application?。
请注意,对MVC项目具有编译时依赖性的AdminJob not 阻止AdminJob作为控制台应用程序运行。这可以很好。
我期望的问题 - 即使您将与View相关的东西移到共享项目中 - 您可能会发现在运行时在网站外运行时它会全部中断。在幕后,有System.Web
个东西的依赖,例如HttpContext
,在运行时将为null。有些依赖项可以存根,有些不可以。
在一个单独的共享项目中根本不能解决这个问题,所以我不认为移动代码可以获得任何收益。
但这里的典型方法(即我工作过的最后6家公司中有5家)是:
忘记命令行的想法。使管理工具成为网站的一部分。无论您想从命令行运行什么,都可以从管理工具上的按钮运行它。
PS
“在我的视图页面中使用非常类似 HTML的电子邮件”是您应该削减的结。
它与视图页面是相同,在这种情况下,您希望AdminJob重用视图页面;或者事实并非如此。在这种情况下,AdminJob应该有自己的HTML。在第二种情况下,采取不存在“类似”HTML的行;如果不一样,那就不一样了。
答案 2 :(得分:0)
我理解将常规网站页面中的html重用到您的电子邮件引擎中的诱惑。但是,我认为这是过度工程的一个很好的例子。与短期利益相比,这将产生更多的长期限制。
考虑几件事:
电子邮件的HTML设计与页面的HTML不同。即使今天它们看起来很相似,但明天它们看起来会有所不同您刚刚说过 - '发送电子邮件与我在视图页面中的HTML 非常相似,您没有说完全相同的HTML'
电子邮件的HTML不应包含任何高级HTML或任何JavaScript。它理想情况下应该有内联CSS而不是JavaScript。与电子邮件客户端兼容的CSS非常有限。标记规则不同于为常规浏览器编写它的自然和现代方式。好的例子是电子邮件客户端对表格友好,而在现代网络中,您现在很少使用表格,特别是如果您想保持响应(跨屏幕平台浏览器)。请阅读此处的所有限制:email-standards.org
现代网络的HTML不必像电子邮件那样是静态的。
这些都是在线商业电子邮件发送者背后的理念。它们可以帮助您创建一个电子邮件分发列表,他们会头疼地生成适当的有限HTML。否则,他们会存在吗?如果不是标记差异,任何人都可以发送群组电子邮件。
我的所有结论:如果您决定使用网页标记来处理电子邮件,则限制两者。你过度工程了。如果您不将常规页面标记重复使用到电子邮件中,则会更加简单。我知道他们今天很相似,但他们可能不会在明天。
显然,为您的电子邮件引擎设置模板功能是个好主意(与重复使用网页标记无关)。为此,您可以使用任何现有的模板引擎,或者您可以快速编写您的文件(毕竟,如果您将HTML消息模板作为字符串,从文件或数据库加载,则脏字符串.Replace()将使用值替换占位符)。
换句话说,要直接回答您的问题:不要犹豫是否将网页和电子邮件的两条路径分开。避免共享功能,因为它们大多不同。考虑两者彼此隔离。