2017-04-11 60 views
1

希望我能讓自己清楚。我在我的mvc項目中有兩個共享佈局區域 _Application.cshtml(對於區域)_Layout.cshtml(對於非區域)MVC區域和共享佈局

報告和收藏夾是區域控制器。
角色和用戶用於默認命名空間控制器。

<li>@Html.ActionLink("Reports", "Reports", "Home")</li> 
<li>@Html.ActionLink("Favourites", "Favourites", "Home")</li> 
<li>@Html.ActionLink("System Roles", "Roles", "Support",new { Area = "" }, htmlAttributes: new { title = "System Roles" }) </li> 
<li>@Html.ActionLink("Users", "Users", "Support", new { Area = "" }, htmlAttributes: new { title = "Users" })</li> 

在角色和用戶視圖中定義我正在定義不同的共享佈局。這沒有鏈接到報告和收藏夾(只是完全不同的導航菜單)。

是否可以將角色和用戶的佈局分配給我的_Application共享佈局,而不會失去從默認命名空間控制器調用操作的能力?

if (this.ViewContext.RouteData.DataTokens["Area"] != null) { 
    Layout = "~/Views/Shared/_Application.cshtml"; 
} 
else 
{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

我試過這個,但DataToken永遠不會收到區域路由,因爲它沒有定義。

編輯:對不起我有描述了這個問題(甚至與同事太...)

區「採購」的麻煩:控制器:「家」有三個視圖索引,報告和收藏夾。導航菜單(_Applicaiton.cshtml)僅適用於採購區域

非區域:控制器「支持」具有兩個視圖角色和用戶。導航菜單(_Layout.cshtml)是通用的,包含導航到項目的其他區域的鏈接

上述操作鏈接駐留在索引視圖中。如果我點擊報告或收藏夾,它會將我導航到ApplicationName/Procurement/Home/Reports或ApplicationName/Procurement/Home/Favorites

如果我單擊角色或用戶,它將導航到ApplicationName/Support/Roles或ApplicationName /支持用戶

由於我已經爲角色和用戶定義了佈局,所以導航菜單默認回到通用窗口,而不是顯示特定於採購區域的佈局。

我在查看是否有可能在單擊導航菜單的角色或用戶時留在採購佈局上並引用相同的支持控制器。我不想爲我創建的每個區域創建角色和用戶頁面。

回答

0

傳統上,您只需使用ViewContext.RouteData.Values["key"]而不是DataTokens。不知道這是否有所作爲。另外,我認爲關鍵是「區域」,而不是「區域」。字典鍵區分大小寫,所以這可能是您的問題。

編輯

好。我想我現在可能會更好一點。要達到您的要求,您需要在採購區域重新實施角色和用戶功能。但是,這並不意味着您必須複製代碼。您可以依靠視圖約定來加載正確的視圖。例如,如果您將角色視圖移動到Views\Shared,則在搜索不同控制器或區域中的視圖時,Razor可以找到它,因爲Views\Shared始終是搜索的最後結果路徑。至於動作本身,您可以利用控制器繼承在一個或多個不同區域實現相同的控制器/動作,而不是實際重複代碼。

+0

你對「區域」小寫是正確的。不過,我認爲這種方法不適合我。我沒有在我的ActionLink中定義區域,因爲那些是我的默認命名空間控制器中的操作,所以密鑰永遠不會被設置... – foop

+0

本質上,我試圖在各個區域中重用角色和用戶視圖和操作項目。不過,我希望給用戶不要爲那些重複使用的視圖和操作留下特定區域的體驗。 – foop

+0

'_Application.cshtml'是否繼承自_Layout.cshtml'? –

2

如果您希望對某些區域進行特定的佈局,則有一個簡單的解決方案。使用_ViewStart文件指定每個區域使用的佈局。

~/Views/_ViewStart.cshtml文件:

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

~/Areas/Xxx/Views/_ViewStart.cshtml文件:

@{ 
    Layout = "~/Views/Shared/_LayoutXxx.cshtml"; 
} 

你可以閱讀ASP.NET MVC 3: Layouts with Razor

不要忘記刪除的意見Layout = "..."聲明,以讓ViewStart做它的工作。

+0

但我所引用的視圖在該特定區域中不存在。 – foop

+0

你的問題很難從你的帖子瞭解。你可以嘗試給我們一個你想要在不同情況下發生的事情的列表(哪個角色,哪個用戶的財產,哪個區域,哪個網址)? – SandRock

0

如果您想有條件地驅動使用哪個視圖,則可以從視圖引擎繼承,並且以每個請求爲基礎覆蓋視圖位置

This post示出了不同的靜態視圖分辨率模式。

您可以覆蓋ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)方法來自定義給定請求的可用視圖。 controllerContext對象將允許您查找用戶及其角色,以便返回正確的視圖。

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
{ 
    if (/* user has role X */) 
    { 
     return new ViewEngineResult(new string[] { "Some View.cshtml" }); 
    } 

    return base.FindView(controllerContext, viewName, masterName, useCache); 
} 

This article顯示如何從經典視圖引擎繼承並聲明它們。 This article顯示瞭如何使用自定義ViewEngine中的請求對象根據用戶的角色選擇視圖。