2017-02-17 99 views
2

大部分我的意見是正常的<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來引用當前應用程序根目錄外的物理文件系統 - 是正確的,任何人都可以幫助我舉一個例子,如果它是?

回答

1

這對我來說似乎是對的。 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); –

相關問題