方法 2:使用强类型类来传递ViewData
除了支持后期绑定的字典方法外,asp.net mvc框架还允许你把强类型的ViewData对象从控制器传递给你的视图。使用这个强类型的方法有几个好处:
避免使用字符串来查询对象,得到对你的控制器和视图代码的编译时检查
避免需要在使用象C#这样的强类型语言中明确转换ViewData对象字典中的值
在你的视图网页的标识文件以及后台代码文件中得到你的ViewData对象的自动代码intellisense
可以使用代码重构工具来帮助自动化对整个应用和单元测试代码库的改动
下面是一个强类型的ProductsListViewData类,封装了 List.aspx 视图显示我们的产品列表所需的数据,它含有 CategoryName 和 Products 属性(是通过使用新的C#自动属性支持来实现的):
然后我们可以更新我们的 ProductsController 实现来使用这个对象, :
注意上面,我们是如何通过 RenderView() 方法的一个额外的参数,把我们的强类型 ProductsListViewData 对象传给View的。
ASP.NET MVC框架中把视图的ViewData字典与强类型的ViewData对象一起使用
前面我们编写的 List.aspx 视图实现会继续和我们更新过的 ProductsController 协作,不需改动代码。这是因为,当把一个强类型的 ViewData 对象传递给继承自 ViewPage 的视图类时,ViewData 字典会自动使用反射对强类型的对象的属性做查询取值。所以我们象下面这样的视图中的代码:
会自动使用反射来从强类型的 ProductsListViewData 对象中获取 CategoryName 属性,这个对象是我们在调用 RenderView 方法时传入的。
使用ViewPage< T>基类来对ViewData强类型化
除了支持基于字典的ViewPage基类外,asp.net mvc框架中还发布有基于泛型的 ViewPage< T> 实现。如果你的视图是从 ViewPage< T> 继承而来,这里T表示是控制器传给视图的 ViewData 的类型,那么 ViewData 属性就将是使用了这个T类的强类型属性。
例如,我们可以更新我们的 List.aspx.cs 后台代码类,不是从ViewPage继承来,而是继承自 ViewPage< ProductsListViewData> :
这么做之后,页面上的 ViewData 属性将会从一个字典变成属于 ProductsListViewData 类型。这意味着,我们现在可以不再使用基于字符串的字典来查阅获取数据,而是可以使用强类型的属性了:
然后,我们可以使用服务器控件的方法,或者 < %= %> 显示的方法来生成基于这个ViewData的HTML。
使用服务器控件来实现 ViewPage< T>视图
下面是一个例子,我们可以使用< asp:literal> 和 < asp:repeater>服务器控件来实现我们的HTML界面。这是我们使用继承自 ViewPage 的 List.aspx 网页时所使用的完全一样的标识:
下面是相应的后台代码。注意,因为我们是从 ViewPage< ProductsListViewData> 继承而来的,我们可以直接访问它的属性,而不要对任何东西做类型转换(什么时候我们决定对其中一个属性改名的话,我们还将得到重构工具的支持):
使用 < %= %> 代码实现我们的 ViewPage< T> 视图
如果你更喜欢使用行内代码来生成输出的话,你可以象下面这样在 List.aspx 中达成跟上面一样的结果:
使用 ViewPage< T> 方法,我们现在不再需要对 ViewData 使用字符串查阅了。更重要的是,注意上面,我们不再需要对任何属性做类型转换了,因为它们已经是强类型的。这意味着,我们可以编写 foreach (var product in ViewData.Products) ,而不用对 Products 做类型转换。我们还在循环中的 product 变量上得到了完整的intellisense:
结语
希望本贴子提供了关于asp.net mvc框架中控制器如何把数据传递给视图以显示返回到客户端的回复的一些细节。你可以使用后期绑定的字典,或者使用强类型的方式来达成这个目的。
【编辑推荐】