文章教程

18.3ASP.NETMVC中的数据传递

8/31/2020 9:52:39 PM 人评论 次浏览

18.3 ASP.NET MVC中的数据传递

在ASP.NET MVC中,数据传递是指控制器和视图之间的数据交互,它包括两个方向上数据的交互,一个是将控制器中设置的数据传递到视图中,在视图中如何显示这些数据,另一个是将视图中的数据传递到控制器中,如何在控制器中读取、处理这些数据。

18.3.1 使用ViewData传递数据

在ASP.NET MVC框架中,所有的控制器必须继承Controller类,而Controller类又是ControllerBase的子类。根据ControllerBase类中的ViewData属性,可以在控制器中的相关动作方法中设置该视图数据字典(ViewDataDictonary)的值,例如在控制器Index动作方法中,对ViewData视图数据字典设置如下代码:

alt

而要在视图页面Index中,读取上述控制器中被设置的ViewData数据,也就是说实现数据从控制器到视图的传递,只需要设置如下代码:

alt

从上述代码中可以看出,在视图页面Index中只需要通过读取该页面ViewPage类中的ViewData属性,即可获得控制器中所设置的ViewData属性值。而ViewData["Message"]实际上是this.ViewDataD["Message"]的简化形式。

18.3.2 使用ViewBag传递数据

ViewBag视图包主要是为了从Controller到View传值用的,类似有此功能的ViewData。ViewBag能动态地Set/Get值,增加任何数量的额外字段而不需要强类型的检测。

ViewBag的使用就相当于ViewData,它跟ViewData一样,都是字典值,但是内在的实现却完全不一样。ViewBag最大的优点就是它不需要转型就可以使用里面的值,因为ViewBag存放的不是键值对,而是dynamic动态类型。例如在控制器Index动作方法中,对ViewBag设置如下代码:

alt

而要在视图页面Index中,读取上述控制器中被设置的ViewData数据,实现数据从控制器到视图的传递,只需要设置如下代码:

alt

ViewBag就是封装了的ViewData,它是顺应C# 4的dynamic关键字而诞生的。

ViewBag在使用上与ViewData并没有孰优孰劣的说法,但是可以肯定,ViewBag比ViewData要慢,但这个可以忽略。值得注意的是,ViewBag可以直接访问存储在ViewData里面的数据(因为它本来就只是封装了的ViewData)。更加重要的是,ViewBag无法作为扩展方法的参数,因为编译器为了确保所选择的扩展方法是正确的,编译时必须知道参数的真正类型,所以,HTML辅助方法无法使用ViewBag。

18.3.3 使用TempData传递数据

根据ControllerBase类中的TempData属性,同样可以在控制器中的相关动作方法中设置该TempData属性的值。在控制器的Index动作方法中,可以对TempData属性设置如下代码:

alt

而要在视图页面Index中,读取上述控制器中被设置的TempData数据,实现数据从控制器到视图的传递,只需要设置如下代码:

alt

从上述代码中可以看出,在视图页面Index中只需要通过读取该页面ViewPage类中的TempData属性,即可获得控制器中所设置的TempData属性值。

需要说明的是,ViewDate和TempData是两个完全不同的数据类型,ViewDate的数据类型是ViewDataDictonary类的实例化对象,而TempData的数据类型则是TempDataDictonary类的实例化对象;ViewDate只能在一个动作方法中或者多个页面中设置、读取,只对当前的视图页面有效,而TempData则可以在多个动作方法中或者多个页面中设置、读取。

18.3.4 使用Model传递数据

通过在控制器的View方法中传递实例化的对象,可以将该对象传递到视图中。当在视图中读取该对象的某些属性时,由于是强类型的,所以书写代码时具有代码智能感知功能,有利于代码书写与查错。

当在控制器View方法中传递实例化对象时,控制器就会将ViewDataDictionary类的实例化对象的Model属性设置成为需要被传递的对象。在视图中,只需要读取ViewPage类中的Model属性,就可以获得控制器中所设置的实例化对象。

例如在HomeController控制器中,设置如下代码:

alt

以上代码将nid.tb_News对象设置为需要被传递的对象,传入View方法中,完成了在控制器端设置需要被传递对象的工作。

然后通过“添加视图”对话框来完成对newsInfo视图的创建。在视图中通过循环遍历model对象就能得到其中的数据。这里需要说明的是在视图页面中设置了ViewPage的类型为IEnumerable<实体数据模型命名空间.tb_News>,正是由于设置了该代码,才使得ViewPage的Model属性为可遍历的tb_News实例化对象。

【实例18-6】使用Model传递数据

本实例在项目的Home文件夹中创建一个视图Categories.aspx显示tb_New数据表中的新闻类别和对应该类别下的所有新闻标题。

01 打开Vistual Studio 2012,创建一个使用ASPX视图引擎的ASP.NET MVC 4 Web应用程序,命名为实例18-6。

02 在该项目中创建一个ADO.NET实体数据模型,命名为db_newsEntities。

03 单击项目根目录下Controllers文件夹中的HomeController.cs文件,在文件中编写如下代码:

alt

在上面的代码中,第1行定义一个名为Categories的动作方法。第2行实例化实体数据模型对象db。第3行创建需要被传递的对象model。第4行将实例化对象model传入View方法中,这样就完成了在控制器中设置需要被传递实例化对象的工作。

04 选择Categorie方法,然后单击鼠标右键,在弹出的快捷菜单中选择“添加视图”命令。

05 打开“添加视图”对话框在“视图引擎”下拉列表中选择ASPX(C#);选中“创建强类型视图”多选按钮;在“视图数据类”下拉列表中找到实体数据类tb_News(MvcApplication4. Modes);在“支架模板”下拉列表中选择Empty列表;选中“引用脚本库”复选按钮;然后选中“选择母版页”多选按钮,在下面的文本框中输入母版页的路径;最后单击“添加”按钮。ASP.NET MVC 4就会自动地在网站根目录Views文件夹下的Home子文件夹下创建Categorie.aspx页面。

06 单击Categories.aspx文件,编辑关键代码如下:

alt

上面的代码中第1行设置@Page指令,由于Model属性被设置为tb_News类的实例化对象,所以ViewPage的类型必须为IEnumerable<MvcApplication6.Models.tb_News。第6行~第21行通过一个表格来显示新闻目录和新闻标题,第10行~第20行设置foreach循环语句遍历数据实体对象Model,其中第13行获得新闻类别,第14行~第17行嵌套foreach循环语句遍历实体数据对象Model;第15行和第16行获取指定新闻类别下的新闻标题。

07 修改程序根目录下App_Start文件夹中的RouteConfig.cs文件,在文件中编写如下代码:

alt

上面的代码中第3行~第7行设置程序的默认URL路由,其中最关键的是将ation属性设置为创建的Categories行为方法。

08 按快捷键Ctrl+F5运行程序的界面如图18-22所示。

alt

图18-22 运行结果

教程类别