【问题标题】:RazorGenerator, Templates, and @HtmlRazorGenerator、模板和@Html
【发布时间】:2012-10-23 16:48:28
【问题描述】:

我正在尝试使用RazorGenerator 作为电子邮件模板引擎。我想用数据建立一个模型,组装正确的部分视图集,并返回我可以通过电子邮件发送的 HTML。
编辑:除了这个工作流程之外,任何解决方案都需要可以作为 .cshtml 文件进行编辑,并且可以编译成 dll。由于各种原因,部署 cshtml 文件本身是不切实际的——如果我们不能将所有剃刀视图嵌入到单个文件中,那么我们就不能使用该建议。因此是 RazorGenerator。

到目前为止,我已经完成了它的每个部分,除了部分。当我尝试在模板文件中使用 @Html.Partial() 时,我得到:The name 'Html' does not exist in the current context

基于this answer,我知道@Html 默认不是Razor 的一部分,关于如何在控制器中创建HtmlHelper 有很多答案。但是,我需要在模板中创建一个模板,该模板没有我需要遵循这些示例的ControllerContext

我也尝试过使用@Include,但 RazorGenerator 模板似乎不支持它。 编辑:我还尝试创建一个继承自TemplateBase<> 的新类并复制RazorTemplateBase 的所有功能,但我在@Include 行上得到NullReferenceExceptions。

所以,我的主要问题是:有没有更好的方法将另一个 Razor 文件(带有模型)包含到我的文件中?

其次,如果没有更好的方法,如何创建 HtmlHelper?


为赏金编辑:重申一下,我在可接受的答案中需要的四件事是:

  1. 能够使用标准编辑器编辑.cshtml 文件(没有“将其存储为字符串”等)
  2. 能够将所有内容编译成单个 dll,可以使用我们当前的构建系统进行部署(我们无法部署大量单独的 .cshtml)
  3. 能够从另一个 .cshtml 文件引用一个 .cshtml 文件,并传递一个模型 - 相当于 @Includes@Html.Partial(如果它们都可以正常工作,则两者都可以接受)
  4. 通过电子邮件发送结果和附件的能力。 (如果结果是字符串或可转换为字符串,我已经有这方面的代码。)

我目前可以得到其中三个的大多数组合,但我不能同时得到所有四个。我愿意接受新的库、替换 RazorGenerator 或丢弃我已有的任何部分,只要结果按需要工作即可。

【问题讨论】:

  • 部分是否在同一个视图文件夹中?我从来没有使用过Html.Partial()
  • 我问只是因为使用该方法您有两个选项来指定部分...Html.Partial("_PartialInSameFolder")Html.Partial("~/Views/Folder/PartialInAnotherFolder.cshtml") 您可能知道这是我能想到的唯一会导致你提到的错误。
  • @Jared - 他不是在生成视图的上下文中执行此操作。他正在尝试使用来自后端类的 Razor 引擎创建 HTML 电子邮件。 '@Html' 在这些情况下不起作用。当我们做同样的事情时,我可以收集到,'@Html' 需要一个 HtmlHelper 参数,其中包含视图的 ViewContext。由于这是在后端-> 没有 ViewContext 这是解决此问题的问题的一部分。我希望 Bobson 能得到一些好的答复,因为我们放弃了尝试在 Razor 模板中使用任何“@Html”项目(想使用“@Html.Raw”)
  • @Tommy gotcha 错过了那部分。
  • @Tommy - 没错。我会很高兴没有@Html 和工作的@Include,但工作的@Html 会更好。

标签: c# asp.net-mvc-3 template-engine razorgenerator


【解决方案1】:

只是一个想法,但是为什么您不能设置其他页面并在您的控制器代码中打开一个 HTTPWebRequest / WebClient 在那里发送您需要的数据,从该视图中获取所有 html/文本,将多个调用合并在一起然后通过电子邮件发送所有字符串。

public ActionResult SomeAction() {
  // call other section logic using HttpWebRequest or WebClient
  // /controller/emailsection/{vars}/......
  // Get the string out of the request add it to ViewData["xxx"]
  // rinse and repeat for other sections

}

public ActionResult EmailSection() {
  //put section logic here

  Response.ContentType = "text/html"; // "text/plain"
  Response.Write("Some HttpWebResponse");
  return null;
}

【讨论】:

  • 我们实际上是把它嵌入到一个 WinForm 应用程序中(这是#2 的部分原因),所以没有地方可以请求它们。理论上,我们可以将页面托管在我们的 Web 服务器上,但这会减慢每个页面的处理速度,并且我们需要一次生成大量此类电子邮件。不过是个好主意。
  • 使用您的 Winform 应用程序部署 IIS Express,然后从本地机器请求中加载它们。
  • 嗯。有趣的想法。我会在明天或周一试一试。
  • 我们目前的计划是采用这个想法的一个变体。我只考虑在我们的网络服务器上托管,但我的一位同事指出,由于大部分使用将来自自动化工作,而不是 WinForm 应用程序,它会使最有意义的做法是建立一个专用的内部网站,在备用服务器上处理这些页面,然后从该网站请求页面以供自动化作业和少数 WinForm 使用。
  • 我们有一个类似的服务器设置,仅用于我们的管理脚本这样的内部作业,此外它还通过 DMZ 为我们的一些网站提供数据。不完全确定您的基础设施是什么样的,所以只是在黑暗中随机拍摄。很高兴我可以呈现不同的视图。
【解决方案2】:

【讨论】:

  • 快速阅读,我认为不是。所有这些似乎都需要某种现有的上下文(查找new ViewContext(ControllerContext) 部分),其目的是在没有任何上下文的情况下呈现它。
  • 第二个链接也用吗?我认为我们可以伪造 HttpContext。
  • 确实如此,但您必须点击源链接,并查看 cmets 以查看人们遇到的与此相关的问题。该页面上的最后一条评论可能在没有上下文的情况下有效,但无论哪种方式都不确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 2011-07-13
相关资源
最近更新 更多