MVC神韵---你想在哪解脱!(八)
从控制器访问模型中的数据
在本节中,我们将要创建一个新的MoviesController类,并且书写代码来获取数据库中的数据,并通过视图模板来显示在浏览器中。
鼠标右击Controllers文件夹,点击“添加”菜单下的“控制器”菜单项,将会弹出一个“添加控制器”对话框,如图:
在该对话框中将控制其命名为MoviesController,然后点击添加按钮,该对话框被关闭。观察解决方案资源管理器中,Controllers文件夹下增加了一个名为MoviesController.cs的文件,并且呈打开状态。让我们更新MoviesController类中的Index方法,以便获取movie(电影)清单。
这里需要注意的是,为了引用我们前面创建的MovieDBContext类,你需要在文件头部追加如下所示的两个using语句。
using MvcMovie.Models;
using System.Linq;
修改MoviesController类中的代码为代码清单所示。
using MvcMovie.Models;
using System.Linq;
using System;
using System.Web.Mvc;
namespace MvcMovie.Controllers
{ public class MoviesController : Controller
{ MovieDBContext db = new MovieDBContext();
public ActionResult Index()
{ var movies=from m in db.Movies
where m.ReleaseDate>new DateTime(1984,6,1)
select m;
return View(movies.ToList());}
}
}
这段代码实施了一个LINQ查询来获取1984年夏天之后发行的所有电影。我们还需要一个视图模板来显示这个电影清单,所以在Index方法内点击鼠标右键,然后点击“添加视图”来添加一个视图。
由于这里我们需要将一个Movie类传递给视图,所以在“添加视图”对话框中,与本教程中前几次在该对话框中之行的操作有所不同,前几次我们都是直接点击添加按钮来创建一个空白的视图模板,但是这一次我们想让Visual Web Developer为我们自动创建一个具有一些默认处理的强类型的视图,所以我们勾选“创建强类型视图”复选框,在模型类下拉框中选择“Movie(MvcMovie.Models)”(如果模型类中不存在这个类,请先点击调试菜单下的“生成MvcMovie”生成该类),在支架模板下拉框中选择“List”,最后勾选“引用脚本”复选框,如图:
点击添加按钮,Visual Web Developer自动生成一个视图,并且自动在视图文件中添加显示电影清单所需要的代码。这里,我们首先用与前面修改HelloWorld控制器所用的视图中的标题同样的方法来修改这个Movies控制器所用视图中的标题。代码清单在下面。在这段代码中,我们将releaseDate(发行日期)属性的格式化字符串从原来的“{0:g}”修改为“{0:d}”(长日期修改为短日期),将Price(票价)属性的格式化字符串从原来的“{0:F}”修改为“{0:c}”(float类型修改为货币类型)。另外,将列表标题中的文字全部修改为中文名称。
@model IEnumerable<MvcMovie.Models.Movie>
@{ ViewBag.Title = "电影清单";}
<h2>我的电影清单</h2>
<p> @Html.ActionLink("追加", "Create")
</p>
<table>
<tr>
<th></th>
<th>电影名称</th>
<th>发行日期</th>
<th>种类</th>
<th>票价</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>@Html.ActionLink("编辑", "Edit", new { id=item.ID }) |@Html.ActionLink("查看明细", "Details", new { id=item.ID }) |@Html.ActionLink("删除", "Delete", new { id=item.ID })
</td>
<td>@item.Title</td>
<td>@String.Format("{0:d}", item.ReleaseDate)</td>
<td>@item.Genre</td>
<td>@String.Format("{0:c2}", item.Price)</td>
</tr>
}
</table>
强类型模型与@model关键字
在前文中,我们介绍了一个控制器可以使用ViewBag对象来将数据或对象传递到视图模板中。ViewBag是一个动态对象,它提供了一种便利的,后期绑定的方法来将信息从控制器传递到视图中。ASP.NET MVC也提供了一种利用强类型的方法来将数据或对象传递到视图模板中。这种强类型的方法为你的编码过程提供了很丰富的编辑时的智能输入提示信息与非常好的编译时的检查。接下来我们将结合这种方法与我们的Movies控制器(MoviesController)与视图模板(Index.cshtml)一起使用。
请注意在我们的MoviesController控制器的Index方法中,我们在调用View()方法时传入了一个参数,代码如下所示。
public class MoviesController : Controller
{ MovieDBContext db = new MovieDBContext();
public ActionResult Index()
{ var movies = from m in db.Movies
where m.ReleaseDate > new DateTime(1984, 6, 1)
select m;
return View(movies.ToList());
}
}
请注意如下这一行代码表示将一个movies列表从控制器传递到了视图中。
return View(movies.ToList());
通过在视图模板文件的头部使用@model语句,视图模板可以识别传入的参数中的对象类型是否该视图模板所需要的对象类型。请记住当我们在创建这个Movies控制器所使用的模板时,我们在“添加视图”对话框中勾选了“创建强类型视图”复选框,在模型类下拉框中选择了“Movie(MvcMovie.Models)”, 在支架模板下拉框中选择了“List”。所以Visual Web Developer自动在我们的视图模板文件的第一行中添加了如下所示的语句。
@model IEnumerable<MvcMovie.Models.Movie>
@model关键字允许我们在视图模板中直接访问在控制器类中通过使用强类型的“模型”而传递过来的Movie类的列表。例如,在我们的Index.cshtml视图模板中,我们可以通过foreach语句来遍历这个强类型的模型,访问其中的每一个Movie对象。代码如下所示。
@foreach (var item in Model) {
<tr><td>@Html.ActionLink("编辑", "Edit", new { id=item.ID }) |@Html.ActionLink("查看明细", "Details", new { id=item.ID }) |@Html.ActionLink("删除", "Delete", new { id=item.ID })</td>
<td> @item.Title </td>
<td> @String.Format("{0:d}", item.ReleaseDate)</td>
<td>@item.Genre</td>
<td>@String.Format("{0:c2}", item.Price)</td>
</tr>
}
因为这里的“模型”是强类型的(IEnumerable<Movie>),所以在循环遍历时“模型”中的每一个项目(“item”)也是一个强类型的Movie对象,可以直接访问该对象的每一个属性。同时这也意味着我们可以在编译时检查我们的代码,同时在书写代码时也可以使用代码编辑器提供的智能输入提示信息,如图: