更改RazorViewEngine以查找特定项目中的视图(.Net Core)

时间:2017-05-30 13:27:52

标签: c# razor asp.net-core

我有一个带有电子邮件项目的应用程序,该项目公开了一个类,使用IRazorViewEngine编译电子邮件模板,然后发送它。

但是,这在几个不同的项目中使用,默认情况下,RazorViewEngine似乎只查看有问题的Web项目的Views文件夹。这意味着我必须跨项目复制相同的视图。

我已经考虑过扩展RazorViewEngine以修改它查找视图的位置,但是每个示例都会更改项目中的哪个文件夹,而不是哪个项目,以及快速查看RazorViewEngine源代码明确地期望应用程序本地路径(即以“〜”或“/”开头),阻止我使用绝对路径或以“../”开头的天真尝试。

有没有办法确保RazorViewEngine(或子类)检查特定(非动态)项目,而不是Web项目调用它?

该应用程序正在使用.Net Core 1.1,RazorEngine似乎不支持

2 个答案:

答案 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 engine

在上下文(不同项目)之外的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
                }
            }
    }