在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,那么我们的问题就解决了。
有人可能会问,为什么要用抽象类呢?
因为,我们这个类需要做的工作只是为母版页加载数据,并没有相对应的其他操作。设置为抽象类可以防止其他类直接调用该类中的方法。
到这里,我们需要给母版页传值的问题已经解决了。