2016-08-25 73 views
1

我正在構建一個演示項目,其中多個租戶將擁有自己的視圖集合。此外,如果租戶沒有專門的視圖,則默認視圖集合將可用。我已經看到了多個關於使用多租戶的代碼方面的教程,每個教程都有自己的數據庫。但觀點方面似乎缺乏。如何在MVC 5中創建多租戶視圖結構5

在僞代碼:

Get Me the User information view 
Get tentantname from current context 
Check /views/{tentantname}/userinfo/index.cshtml 
if found return /views/{tentantname}/userinfo/index.cshtml 
else return /views/base/userinfo/index.html 

我不能確定在哪裏處理這個代碼? (創建一個覆蓋通話的基本控制器,以查看也許) 我應該創建我自己的RazorViewEngine版本嗎?
這是在路由配置中處理? (這是更多的控制器路由,然後在哪裏尋找視圖) 需要覆蓋哪些方法?

我找到了關於更改所有視圖的基礎目錄的教程,但我正在尋找按具體情況處理每個視圖的查找。利用運行請求當前上下文中的值。

編輯參考第一個答案。

對RazorViewEngine所做的更改除去了示例中使用的許多可覆蓋的方法。同一作者添加了更新http://weblogs.asp.net/imranbaloch/custom-viewengine-aspnet5-mvc6 但是這個版本並沒有進入視圖位置檢查和重寫。我認爲答案是在傳遞給構造函數的參數之一中。我認爲如果可以覆蓋他們,我可以完成我的任務。這裏是來自元數據的RazorViewEngine:

// 
// Summary: 
//  Default implementation of Microsoft.AspNet.Mvc.Razor.IRazorViewEngine. 
// 
// Remarks: 
//  For ViewResults returned from controllers, views should be located in Microsoft.AspNet.Mvc.Razor.RazorViewEngine.ViewLocationFormats 
//  by default. For the controllers in an area, views should exist in Microsoft.AspNet.Mvc.Razor.RazorViewEngine.AreaViewLocationFormats. 
public class RazorViewEngine : IRazorViewEngine, IViewEngine 
{ 
    // 
    // Summary: 
    //  Initializes a new instance of the Microsoft.AspNet.Mvc.Razor.RazorViewEngine 
    //  class. 
    // 
    // Parameters: 
    // pageFactory: 
    //  The page factory used for creating Microsoft.AspNet.Mvc.Razor.IRazorPage instances. 
    public RazorViewEngine(IRazorPageFactory pageFactory, IRazorViewFactory viewFactory, IOptions<RazorViewEngineOptions> optionsAccessor, IViewLocationCache viewLocationCache); 

    // 
    // Summary: 
    //  Gets the locations where this instance of Microsoft.AspNet.Mvc.Razor.RazorViewEngine 
    //  will search for views within an area. 
    // 
    // Remarks: 
    //  The locations of the views returned from controllers that belong to an area. 
    //  Locations are composite format strings (see http://msdn.microsoft.com/en-us/library/txafckwd.aspx), 
    //  which contains following indexes: {0} - Action Name {1} - Controller Name {2} 
    //  - Area name The values for these locations are case-sensitive on case-senstive 
    //  file systems. For example, the view for the Test action of HomeController should 
    //  be located at /Views/Home/Test.cshtml. Locations such as /views/home/test.cshtml 
    //  would not be discovered 
    public virtual IEnumerable<string> AreaViewLocationFormats { get; } 
    // 
    // Summary: 
    //  Gets the locations where this instance of Microsoft.AspNet.Mvc.Razor.RazorViewEngine 
    //  will search for views. 
    // 
    // Remarks: 
    //  The locations of the views returned from controllers that do not belong to an 
    //  area. Locations are composite format strings (see http://msdn.microsoft.com/en-us/library/txafckwd.aspx), 
    //  which contains following indexes: {0} - Action Name {1} - Controller Name The 
    //  values for these locations are case-sensitive on case-senstive file systems. 
    //  For example, the view for the Test action of HomeController should be located 
    //  at /Views/Home/Test.cshtml. Locations such as /views/home/test.cshtml would not 
    //  be discovered 
    public virtual IEnumerable<string> ViewLocationFormats { get; } 

    // 
    // Summary: 
    //  Gets the case-normalized route value for the specified route key. 
    // 
    // Parameters: 
    // context: 
    //  The Microsoft.AspNet.Mvc.ActionContext. 
    // 
    // key: 
    //  The route key to lookup. 
    // 
    // Returns: 
    //  The value corresponding to the key. 
    // 
    // Remarks: 
    //  The casing of a route value in Microsoft.AspNet.Mvc.ActionContext.RouteData is 
    //  determined by the client. This making constructing paths for view locations in 
    //  a case sensitive file system unreliable. Using the Microsoft.AspNet.Mvc.Abstractions.ActionDescriptor.RouteValueDefaults 
    //  for attribute routes and Microsoft.AspNet.Mvc.Abstractions.ActionDescriptor.RouteConstraints 
    //  for traditional routes to get route values produces consistently cased results. 
    public static string GetNormalizedRouteValue(ActionContext context, string key); 
    // 
    public RazorPageResult FindPage(ActionContext context, string pageName); 
    // 
    public ViewEngineResult FindPartialView(ActionContext context, string partialViewName); 
    // 
    public ViewEngineResult FindView(ActionContext context, string viewName); 
} 

如果你注意到只有兩個屬性是虛擬的。我認爲其中一個構造函數參數可以被覆蓋,以便在調用FindView()時可以完成某些操作。我不知道在這一點上,我找不到一個例子或教程。

回答

2

是的,你會創建自己的CustomViewEngine,它繼承自RazorViewEngine。在那裏,您將從上下文中讀取tenantname,然後指定要查找的路徑。

這是blog post describing creating your own ViewEngine

更新:您也應該檢查View Location Expander

+0

我看着那個教程,但在MVC 5顯著改變了RazorViewEngine類特別的唯一虛擬propertoes是AreaViewLocationFormats和ViewLocationFormats。該FindView不是虛擬的。我相信構造函數中的一個參數可能是答案,但我無法找到關於它們的信息。 (IRazorViewFactory可能是關鍵)。 – Dan

+1

@dan,你有checkec視圖位置昂貴嗎? http://weblogs.asp.net/imranbaloch/view-location-expander-aspnet5-mvc6 – user960567

+0

@ user960567這就是答案!把它放下,我會給你信貸。它的一個恥辱伊姆蘭在他的其他兩個解決方案中並沒有與此相關。我知道這並不複雜。 – Dan