我有一个带有电子邮件项目的应用程序,该项目公开了一个类,使用IRazorViewEngine编译电子邮件模板,然后发送它。
但是,这在几个不同的项目中使用,默认情况下,RazorViewEngine似乎只查看有问题的Web项目的Views文件夹。这意味着我必须跨项目复制相同的视图。
我已经考虑过扩展RazorViewEngine以修改它查找视图的位置,但是每个示例都会更改项目中的哪个文件夹,而不是哪个项目,以及快速查看RazorViewEngine源代码明确地期望应用程序本地路径(即以“〜”或“/”开头),阻止我使用绝对路径或以“../”开头的天真尝试。
有没有办法确保RazorViewEngine(或子类)检查特定(非动态)项目,而不是Web项目调用它?
该应用程序正在使用.Net Core 1.1,RazorEngine似乎不支持
答案 0 :(得分:2)
让RazorLight工作时遇到了一些麻烦,所以我认为我最好在这里发布我的解决方案。我使用以下.csproj更改
将.cshtml文件嵌入到程序集中dput(finalout)
structure(list(c1 = structure(1:2, .Label = c("t1", "t3"), class = "factor"),
c2 = structure(c(2L, 1L), .Label = c("t1", "t2"), class = "factor")), .Names = c("c1",
"c2"), class = "data.frame", row.names = c(NA, -2L))
然后,我在与模板相同的文件夹中包含了一个空类(FakeClass),并使用它与RazorLight EngineFactory一样使用
<ItemGroup>
<EmbeddedResource Include="Emails/*.cshtml" />
<Content Include="Emails/*.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
由于我不理解的原因,如果不查看源,CreateEmbedded需要与视图位于同一位置的类,否则在查找视图时会出错。
名称只是没有扩展名的模板名称,而模型是强类型模型。
这种方法的优点是不需要弄乱路径字符串,并且它可以很好地包含在一个项目中。
答案 1 :(得分:1)
我在控制器中读取视图作为文件,我将使用该字符串进行razor编译。
控制器:
_emailBuilder = new RazorHtmlBuilder();
var tempatePath =
HttpContext.Current.Server.MapPath("~/Views/Mail/HelloFriend.cshtml");
string template = File.ReadAllText(tempatePath);
var body = _emailBuilder.BuildEmail("someUniqueId", template , new Friend() {Name: "John"});
在上下文(不同项目)之外的Razor Email Builder
using System;
using RazorEngine;
using RazorEngine.Templating;
namespace Project.ServiceLayer.Helpers.EmailBuilder
{
public class RazorHtmlBuilder
{
public string BuildEmail<T>(string templateName, string template, T model)
{
try
{
return Engine.Razor.RunCompile(template, templateName, typeof (T), model);
}
catch (Exception ex)
{
//log error
}
}
}