在 ASP.NET MVC Core 控制器的建構子中設置 ViewBag 屬性
我的主題有某種麵包屑。控制器始終是類別。為了避免重複自己,我想在控制器的建構子中為所有這樣的操作設置它:
class MyController:Controller{ public MyController() { ViewBag.BreadcrumbCategory = "MyCategory"; } }當我
ViewBag.BreadcrumbCategory在佈局視圖中訪問時,它為空。在一個動作中它起作用:class MyController:Controller{ public IActionResult DoSomething() { ViewBag.BreadcrumbCategory = "MyCategory"; } }我想知道在建構子中設置 ViewBag 屬性是不可能的?在執行此工作的每個操作上呼叫一個函式會很煩人,也不是一個好的做法。在另一個問題中,使用建構子是一個公認的答案,但正如我所說,這不起作用,至少對於 ASP.NET Core 而言。
有一個關於它的GitHub 問題,據說這是設計使然。您連結的答案是關於 ASP.NET MVC3,舊的遺留 ASP.NET 堆棧。
ASP.NET Core 是從頭開始編寫的,並使用不同的概念,專為可移植性(多平台)以及性能和現代實踐而設計,例如對依賴注入的內置支持。
最後一個使得無法
ViewBag在建構子中設置,因為Constructor基類的某些屬性必須通過 Property Injection 注入,因為您可能已經註意到您不必在派生控制器中傳遞這些依賴項。這意味著,當
Controller呼叫 的建構子時HttpContext,ControllerContext不會設置 等的屬性。它們僅在呼叫建構子並且存在對此對象的有效實例/引用後才設置。正如 GitHub 問題中所指出的,它不會被修復,因為這是設計使然。
正如您在此處看到的,ViewBag 依賴於
ViewData並ViewData在控制器初始化後填充。如果您呼叫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) { base.OnActionExecuting(context); var controller = context.Controller as Controller; if (controller != null) { controller.ViewBag.BreadcrumbCategory = _name; } } }現在你應該可以用它來裝飾你的控制器了。
[BreadCrumb("MyCategory")] class MyController:Controller { }