在ASP.NET Core MVC中,是否可以从项目文件夹外添加View文件夹?

时间:2017-02-17 13:04:53

标签: asp.net-core-mvc

我的大多数视图都是普通<action>.cshtml文件夹层次结构中的常规/Views/<Controller>文件。这些是git中的源代码控制,并以通常的“rip and replace”方式部署。

但是我也使用Razor渲染模板来创建HTML电子邮件,电子邮件.cshtml模板特定于每个客户端。因此,我希望能够从外部 Application Root文件夹加载和呈现它们,因此在部署期间不会丢失特定于客户端的自定义。

我已经成功创建并注册了IViewLocationExpander接口的实现,这适用于Application Root中的文件夹:

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;
    }
}

它似乎不适用于Application Root相对之外的路径,例如, /../Templates似乎不起作用。

我目前还依赖于为我的电子邮件模板设置自定义_ViewStart.cshtml,并且阅读Mvc source code让我认为我唯一的选择是实施自定义IFileProvider来引用当前应用程序根目录之外的物理文件系统 - 是正确的,任何人都可以帮我一个例子吗?

1 个答案:

答案 0 :(得分:1)

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

这是一篇关于实施IFileProvider的非常好的文章。这些文章演示了创建和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端点提供文件。你可以从任何你喜欢的地方获得它们。

相关问题