,是否可以从项目文件夹外部添加View文件夹?

问题描述:

大部分我的意见是正常的<action>.cshtml文件在正常的/Views/<Controller>文件夹层次结构。这些源代码在git中进行控制,并以通常的“拆卸和替换”方式进行部署。,是否可以从项目文件夹外部添加View文件夹?

但是我也使用Razor来渲染模板来创建HTML电子邮件,并且电子邮件.cshtml模板是特定于每个客户端的。因此,我希望能够从以外的应用程序根目录文件夹加载并呈现它们,以便在部署期间不会丢失特定于客户端的定制。

我已经成功地创建并注册了IViewLocationExpander接口的实现,这适用于应用程序的根文件夹内:

public class EmailViewLocationExpander : IViewLocationExpander 
{ 
    protected readonly String _TemplateFolder; 

    public EmailViewLocationExpander(String TemplateFolder) 
    { 
     _TemplateFolder = TemplateFolder.Trim('/'); 
    } 

    public void PopulateValues(ViewLocationExpanderContext context) 
    { 
    } 

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) 
    { 
     var result = new List<String>(viewLocations); 

     result.Add($"/{ _TemplateFolder }/Email/{{0}}.cshtml"); 
     result.Add($"/{ _TemplateFolder }/Shared/{{0}}.cshtml"); 

     return result; 
    } 
} 

它似乎并不比应用程序根目录相对其他路径工作,所以如/../Templates似乎不起作用。

我目前还依赖于其定制_ViewStart.cshtml我的电子邮件模板,并读取Mvc source code使我认为,我唯一的选择就是实现一个自定义IFileProvider来引用当前应用程序根目录外的物理文件系统 - 是正确的,任何人都可以帮助我举一个例子,如果它是?

这对我来说似乎是对的。 ViewLocationExpander处理相对于wwwroot文件夹的路径,所以它不会对指定到其之外的文件的路径有用。

这是一篇关于实施IFileProvider的不错文章。这篇文章演示如何创建和访问存储在数据库中的视图,但是从文件系统中读取它们会更容易。所以这是一个很好的考虑要点。 https://www.mikesdotnetting.com/article/301/loading-asp-net-core-mvc-views-from-a-database-or-other-location

我注意到的一件事是,IFileProvider的工作方式非常酷。您将自定义实现注册为RazorViewEngine的一个选项,如下所示,当ViewEngine需要获取文件时,它将按顺序询问每个FileProvider,直到返回该文件。

public void ConfigureServices(IServiceCollection services) 
{ 
    string customLocation = @"c:\mylocation\" 

    // Add framework services. 
    services.AddMvc(); 
    services.Configure<RazorViewEngineOptions>(opts => 
     opts.FileProviders.Add(
      new MyCustomFileProvider(customLocation) 
     ) 
    ); 
} 

所以在最后,你基本上只是实现您FileProvider提供文件,对一些特定的URL端点。你可以从任何你喜欢的地方获得它们。

+1

我已经阅读了一些显示Mvc只接受单个文件提供程序的旧文档,所以我花了一段时间寻找CompositeFileProvider(现在是.NET核心中的一件事)来将默认和自定义位置合并为一个单一的IFileProvider,但现在(我使用v1.1)它肯定是一个IList ,是的,它很容易实现,就像你描述的一样,它的功能就像一个魅力。谢谢。 –

+1

在我的情况我刚创建用于我的备用位置另一PhysicalFileProvider: \t services.Configure ( \t \t OPTS => \t \t { \t \t \t opts.FileProviders。加入( \t \t \t \t新PhysicalFileProvider(路径) \t \t \t); \t \t} \t); –