在这一小节,我们将会创建一个新的MoviesController类并且写代码来检索movie有关的数据,最后使用视图模板来进行展示。
在继续下一步之前,然我们先将程序生成以下。
右键单击Controllers文件夹创建一个新的MovieController,如果你没有先生成一下(右键单击项目,Build)的话,下面这些选项是不会出现的:
- Controller name:MoviesController。
- Template:MVC Controller with read/write actions and views,using Entity Framework。
- Model class:Movie(MvcMovie.Models)。
- Data context class:MovieDBContext(MvcMovie.Models)。
- Views:Razor(CSHTML)。
点击“Add”,Visual Studio将会创建如下的文件和文件夹:
- 在项目的Controllers文件夹下新建MoviesController.cs文件
- 在项目的Views文件夹下新建Movies文件夹。
- 在新的Views\Movies文件夹下新建Create.cshtml,Delete.cshtml,Details.cshtml,Edit.cshtml和Index.cshtml
ASP.NET MVC 4会自动创建CRUD(create,read,update和delete)的action方法和视图(自动创建crud action和视图的行为被称之为scaffolding)。现在我们有了一个完整功能的web应用,可以让我们对电影数据进行创建,编辑,浏览和删除。
运行程序通过在地址栏的URL后面添加/Movies来访问MoviesController。因为我们的应用程序依赖于默认的路由规则(定义在Global.asax文件里),请求http://localhost:xxxx/Movies时会被自动路由到MoviesController的Index action方法。换句话说,请求http://localhost:xxxx/Movies和请求http://localhost:xxxx/Movies/Index是一样的。返回的结果是一个空的列表,因为我们现在还没有任何数据。
新建一个Movie
选择Create New超链接。输入一部电影的细节数据然后单击Create按钮。
单击Create按钮使表单提交到服务器,服务器会将movie的数据保存到数据库中。然后再次浏览/Movies,这次可以看到新添加的数据了。
多创建一些数据,试一试Edit,Details和Delete超链接,这些都是可用的。
来看看生成的代码
打开Controllers\MoviesController.cs文件来查看一下生成的Index方法。下面展示了MoviesController中的一部分代码.
public class MoviesController : Controller
{
private MovieDBContext db = new MovieDBContext();
//
// GET: /Movies/
public ActionResult Index()
{
return View(db.Movies.ToList());
}
下面的代码实例化了一个前面提到过的MovieDbContext对象,是movie数据库的上下文,你可以使用它了查询,编辑和删除数据。
private MovieDBContext db = new MovieDBContext();
对MoviesController的请求会返回数据库中Movies表的所有数据并且将这些数据传递到Index的view中。
强类型模型和@model关键字
在前面的文章里,我们知道了一个controller如何通过ViewBag对象来为View模板传递数据。ViewBag对象是一个动态对象,可以提供一种方便的,晚期绑定的方式来为view传递数据。
ASP.NET MVC同样提供了为View模板传递强类型数据的能力。这种强类型数据提供了更好编译时的代码检查和Visual Studio的智能提示。scaffolding机制使用了这种方法来创建MoviesController和视图模板中的方法和view。
在Controllers\MoviesController.cs文件中查看生成的Details方法,MoviesController中Details方法的代码如下。
// // GET: /Movies/Details/5 public ActionResult Details(int id = 0) { Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); }
如果能找到指定id的数据,一个Movie对象的实例就会传递给Deatils的视图。来看一下Views\Movies\Details.cshtml文件。
通过在视图模板顶部引入@model语句我们可以指定视图期望使用的对象类型。当我们创建Moviescontroller的时候,Visual Studio自动在Details.cshtml文件的顶部包含了下面的语句
@model MvcMovie.Models.Movie
@model指令允许我们通过强类型的的Model对象来访问Controller传递给View的电影数据。例如,在Details.cshtml模板里,代码中通过强类型的Model对象向DisplayNameFor和DisplayFor方法传递需要的Movie对象的数据。Create和Edit方法还有视图模板中都是传递的Movie类型的Model对象。
让我们仔细查看一下Index.cshtml和MoviesController.cs里定义的Index方法里的内容,注意一下Index方法中的代码中在调用View方法时是如何创建List对象的,代码把创建的List对象从controller传递到了view。
public ActionResult Index() { return View(db.Movies.ToList()); }
当创建MoviesController的时候,Visual Studio会自动在Index.cshtml页面顶部添加@model语句
@model IEnumerable<MvcMovie.Models.Movie>
这条@model指令允许我们通过使用强类型的Model对象访问controller传递给view的数据。例如,在Index.cshtml模板里,代码通过一个foreach语句遍历Model对象。
@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Genre) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID }) </td> </tr> }
因为Model对象是强类型的(是IEnumerable<Movie>对象),在foreach循环中的item是Movie类型。这就是说我们可以获得编译时安全检查和VS的智能提示的支持。
与数据库一起工作
注:原文使用Visual Studio 2012自带的Sql Server LocalDB数据库,本文使用的是Visual Stuio 2010自带的Sql Server Express
Entity Framework的Code First模式会探测到数据库连接字符串指向了还不存在的Movies数据库,所以Code First会自动创建这个数据库。你可以通过查看App_Data文件夹来验证这一点。如果你看不到Movies.mdf文件,单击解决方案资源管理器上方工具条中的"Show All Fiels"按钮,单击"Refresh"按钮,然后展开App_Data文件夹.
双击Movies.mdf来打开数据库浏览器,展开Tables文件夹来看一下Movie表
右键单击Movies表选择"Show Table Data"来查看我们创建的数据
右键单击Movies表,选择"Open Table Definition"来看一下Entity Framework Code First来为我们创建的表结构
注意Movies表结构是如何与我们之前创建的Movie类对应起来的。Entity Framework Code First根据Movie类自动创建表结构.
当你完成这些操作的时候,右键单击数据库选择"Close Connection",如果不这么做的话,下次打开项目可能会报错.
现在我们有了一个简单的页面来展示数据库里的数据了。在下一篇文章里,我们将会查看剩余的自动生成的代码,并且添加一个SearchIndex方法和一个SearchIndex视图来查找数据库里的数据。