2016-10-30 42 views
6

我的主題有某種麪包屑。控制器始終是類別。爲了避免重複自己,我想將它設置在控制器的構造像這樣所有操作:在ASP.NET MVC核心控制器的構造函數中設置ViewBag屬性

class MyController:Controller{ 
    public MyController() { 
     ViewBag.BreadcrumbCategory = "MyCategory"; 
    } 
} 

當我訪問佈局視圖ViewBag.BreadcrumbCategory,其空。在行動它的作品:

class MyController:Controller{ 
    public IActionResult DoSomething() { 
     ViewBag.BreadcrumbCategory = "MyCategory"; 
    } 
} 

我想知道在構造函數中設置ViewBag屬性是不可能的?在做這項工作的每一個動作上都有一個函數需要調用會很麻煩,也沒有好的做法。在another question使用構造函數是一個公認的answear,但正如我所說這不起作用,至少對於ASP.NET Core。

+3

您應該使用操作過濾器。 – SLaks

回答

9

有一個關於它的GitHub issue,它表明這是設計。您鏈接的答案是關於ASP.NET MVC3,舊的傳統ASP.NET堆棧。

ASP.NET Core是從頭開始編寫的,它使用不同的概念,爲可移植性(多平臺)以及性能和現代實踐(如內置的依賴注入支持)而設計。

最後一個使得它不可能設置在構造ViewBag,因爲Constructor基類的某些屬性必須通過物業注射注射,因爲你可能已經注意到了,你不必在你的派生控制器通過這些依賴。

這意味着,當調用Controller的構造函數時,將不會設置HttpContext,ControllerContext等的屬性。它們僅在調用構造函數後設置爲,並且存在對該對象的有效實例/引用。

正如GitHub問題所指出的那樣,它不會被修復,因爲這是通過設計。

正如你可以看到here,ViewBag依賴ViewDataViewData是在控制器初始化後填充。如果調用ViewBag.Something = "something",那麼它將創建一個DynamicViewData類的新實例,它將在構造函數初始化後由一個實例替換。

正如@SLaks指出的那樣,您可以使用您爲每個控制器配置的操作過濾器。

以下示例假定您總是從Controller基類中派生出您的控制器。現在

public class BreadCrumbAttribute : IActionFilter 
{ 
    private readonly string _name; 

    public BreadCrumbAttribute(string name) 
    { 
     _name = name; 
    } 

    public void OnActionExecuting(ActionExecutingContext context) 
    { 
     await base.OnActionExecuting(context); 

     var controller = context.Controller as Controller; 
     if (controller != null) 
     { 
      controller.ViewBag.BreadcrumbCategory = _name; 
     } 
    } 
} 

你應該能夠用它來裝飾您的控制器。

[BreadCrumb("MyCategory")] 
class MyController:Controller 
{ 
} 
相關問題