在MVC中,我們會遇到這樣的場景:
我們需要在每一頁中都顯示地區信息,這些地區信息都是存儲在數據庫當中的。
那我們需要在模板頁中顯示地區信息,問題出來了,怎么在視圖母版頁面里從數據庫檢索這些地區信息?
直接在視圖中操作數據庫檢索數據?這樣的確很方便,但是這樣就違反了MVC的設計初衷,Model-View-Controller,就是為了將關注點進行分離,當然這也是MVC的優點之一。
在MVC中,所有的Model的傳遞和交換都應該由Controller來進行,這樣做會加強系統的可維護性以及可擴展性。也就是說所有傳往視圖的數據都應該由控制器來控制。
那這么說來,我們應該如何將數據傳遞到母版頁視圖(_Layout.cshtml)呢?
方法一:
我們可以在控制器內的每個方法中,為母版頁傳遞數據!
也就是說在控制器的沒個方法中給ViewData進行賦值。這么做確實能實現,但是每個方法內都要寫這么一段代碼。
問題在於:DRY!
Don’t Repeat Yourself!
每一個方法內都加一段讀取數據的代碼會提高程序的復雜度,造成后續的維護困難,那我們應該怎么做呢,別着急,往下看!
方法二:
既然不能這么重復的寫代碼,那我們就換個思路。
因為我們只需要對母版頁視圖傳遞一次數據就好了。
那我們就將從數據庫中讀取數據的操作放在控制器的構造方法中,這樣就避免了要在每個方法中都加上相同的代碼。
但是這樣之后,細心的同學又會發現,那豈不是我每個控制器的構造方法中都需要加上這么一段代碼,還是違反了DRY。
沒錯,那么這里我們就要用到面向對象的特性:封裝、繼承、多態中的繼承。
我們可以定義一個抽象類BaseController,讓BaseController繼承於System.Web.Mvc.Controller。
然后在BaseController的構造方法中,我們對ViewData進行賦值。
在項目中其他的控制器里,我們讓控制器繼承於BaseController,那么我們的問題就解決了。
有人可能會問,為什么要用抽象類呢?
因為,我們這個類需要做的工作只是為母版頁加載數據,並沒有相對應的其他操作。設置為抽象類可以防止其他類直接調用該類中的方法。
到這里,我們需要給母版頁傳值的問題已經解決了。