mvc
入门基础篇
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
本书定价:9元
EntLib.com 团队感谢您的支持!
您的支持是EntLib.com 团队不断发展的动力,我们会提供更好的产品和服务。
EntLib.com团队
禁止任何个人、公司和网站,将本电子书分享下载! 这是EntLib.com团队成长的需要,感谢您的支持! 授权用户信息:
姓名:郝斌(744827451@qq.com) 订单编号:480830580841544
http://www.EntLib.com
2
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
关于EntLib.com团队
EntLib.com团队专注于ASP.NET/C#/MVC/SQL Server 开源电子商务系统和iPhone/iPad、Windows Phone和Android移动平台开发技术。
欢迎电商和互联网同行分享和交流心得,让中国软件开发人员也为电子商务行业的繁荣奉献一点点力量。
EntLib 官方微博(新浪):EntLib开源电子商务平台(请关注我们)
EntLib电子商务系统 – QQ 群:255261329 交流ASP.NET、MVC、SQL Server、电子商务系统。
业务合作请联系:
QQ:1665600601 (请注明业务合作)
http://www.EntLib.com
3
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
目 录
本书定价:9元 ................................................................................................................... 2 关于ENTLIB.COM团队 ........................................................................................................ 3 目 录 .................................................................................................................................. 4 第一章 ASP.NET MVC 4 入门简介 ...................................................................................... 6 安装ASP.NET MVC 4 ............................................................................................................. 6 部署ASP.NET MVC 4 应用程序 ............................................................................................ 6 创建 ASP.NET MVC 4 应用程序 ........................................................................................... 6 MVC 应用程序的结构 ....................................................................................................... 12 ASP.NET MVC 和约定 ......................................................................................................... 15 第二章 控制器(CONTROLLER) ...................................................................................... 16 HOME CONTROLLER控制器 .................................................................................................... 16 编写第一个控制器 ............................................................................................................. 19 创建新的控制器................................................................................................................. 19 编写ACTION方法 ................................................................................................................ 21 控制器方法中的参数 ......................................................................................................... 23 第三章 视图(VIEWS) .................................................................................................... 25 分析HOME视图 ................................................................................................................. 25 添加视图 ............................................................................................................................ 26 修改视图和布局页面 ......................................................................................................... 30 从控制器传递数据给视图 ................................................................................................. 33 第四章 模型(MODEL) ................................................................................................... 38 添加模型类 ........................................................................................................................ 38 创建连接字符串和SQL SERVER数据库 .............................................................................. 40 第五章 从控制器中访问模型数据 .................................................................................... 41 创建MOVIESCONTROLLER控制器 .......................................................................................... 41 创建一条新的MOVIE记录 ................................................................................................. 43
http://www.EntLib.com
4
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
检查自动生成的代码 ......................................................................................................... 44 强类型模型和@MODEL关键字 ........................................................................................... 45 检查SQL SERVER数据库 ..................................................................................................... 47 检查EDIT 方法和EDIT 视图 ............................................................................................... 49 处理POST请求 .................................................................................................................. 54 添加SEARCH方法和SEARCH视图 ........................................................................................ 56 显示SEARCHINDEX表单 ....................................................................................................... 56 添加按类型(GENRE)搜索 ............................................................................................... 63 SEARCHINDEX视图支持按类型查询 ..................................................................................... 64 第六章 在MOVIE模型和表中添加一个新的字段 ........................................................... 66 为模型更新设置CODE FIRST 迁移 ....................................................................................... 66 在MOVIE模型中新增RATING属性 ..................................................................................... 72 第七章 在模型类中添加验证逻辑 .................................................................................... 80 保持DRY(DON’T REPEAT YOURSELF) .................................................................................. 80 在MOVIE模型中添加验证规则 .......................................................................................... 80 用户界面验证错误信息 ..................................................................................................... 83 CREATE视图和CREATE动作方法中的验证代码 ................................................................... 84 为MOVIE模型添加格式化属性 .......................................................................................... 87 第八章 检查DETAILS和DELETE方法 ............................................................................... 89 检查DETAILS和DELETE方法 ................................................................................................ 89 总 结 .................................................................................................................................. 91
http://www.EntLib.com
5
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
第一章 ASP.NET MVC 4 入门简介
安装ASP.NET MVC 4
ASP.NET MVC 4 开发包支持Visual Studio 2010 和 Visual Studio 2012,包括对应的免费Express 版本。MVC 4 已经包含在Visual Studio 2012中了,如果安装了Visual Studio 2012,就不必安装了。如果使用Visual Studio 2010,可以通过Web Platform Installer (http://www.microsoft.com/web/gallery/install.aspx?appid=MVC4VS2010)来安装。
部署ASP.NET MVC 4 应用程序
如果在Server上安装好ASP.NET MVC 4,MVC 运行时程序集会安装到Global Assembly Cache(GAC)中,表示这些程序集对所有运行在该Server上的站点都可以使用。 如果在Server上没有安装ASP.NET MVC 4,在ASP.NET MVC 4 之前,可以使用bin 发布,也就是在Visual Studio 开发工具中手动设置程序集复制到本地(Copy Local)。在ASP.NET MVC 4 之后,所有的程序集通过NuGet引用包含进来了。这样,所有需要的程序集都自动添加到项目中的bin目录,任何MVC 4 应用程序都支持bin 发布。
创建 ASP.NET MVC 4 应用程序
本教程所有示例截图采用Visual Studio 2012开发工具,和使用Visual Studio 2010 开发工具开发ASP.NET MVC 4 应用程序界面基本一致。 创建一个新的MVC项目:
http://www.EntLib.com
6
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
1. 选择文件 > 新建 > 项目菜单项,打开新建项目窗口。
选择ASP.NET MVC 4 Web Application,将应用程序命名为MvcMovie,点击OK按钮。 接下来,将弹出一个MVC项目模板窗口,下面是一些预先安装好的项目模板。
http://www.EntLib.com
7
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
http://www.EntLib.com
8
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
Internet 应用程序模板 – 包含MVC web应用程序的开始部分,这样可以在创建好应用程序之后,就可以马上运行应用程序了。这个模板包含了基于ASP.NET Membership system的一些基本账号管理功能。
Intranet应用程序模板 – 在ASP.NET MVC 3 Tools Update中增加了这个模板,和Internet Application模板相似,但是账号管理功能是基于Windows账号,而不是ASP.NET Membership system。
基本(Basic)模板 – 这个模板非常小,包含有基本的文件夹,CSS和MVC应用程序基础架构。运行该模板创建的项目将出现错误。基本模板适用于有经验的MVC开发人员,开发
http://www.EntLib.com
9
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
人员希望按照自己的需要设置和配置应用程序。
空(Empty)模板 – 基本(Basic)模板之前成为空模板,但是开发人员抱怨并不是真正的空模板。在ASP.NET MVC 4 中,之前的空模板更名为基本模板,新的空模板则是空的,它包含有程序集和基本的目录结构。
移动应用程序模板(Mobile Application template) - 移动应用程序模板配置为jQuery Mobile,用来创建面向移动终端的网站。它包含有移动可视化主题、触摸优化用户界面和支持Ajax导航。
Web API 模板 – ASP.NET Web API是用来创建HTTP services的框架。Web API模板和Internet应用程序模板比较相似,但为Web API开发进行了简化。例如,它没有用户账号管理功能,因为Web API 账号管理通常和标准MVC账号管理不同。在其他MVC项目模板中也有Web API功能,甚至在非MVC项目类型中。 视图引擎
在新ASP.NET MVC 4 项目对话框中另外一个选项是视图引擎下拉列表。视图引擎提供了在MVC应用程序中不同模板语言来生成HTML标记。在MVC 3 之前,视图引擎仅有内置的ASPX。在MVC 3 中添加了新的选项:Razor 视图引擎。
测试
所有内置项目模板都提供选项创建一个单元测试项目,并提供了示例单元测试。
http://www.EntLib.com
10
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
如果不勾选创建单元测试项目复选框,则项目不会创建任何单元测试。
在选择创建单元测试项目复选框后,可以看到如下选择: 第一个是单元测试项目的名称,可以修改;
第二个是选择测试框架;默认只有一个测试框架选项,如果我们按照其他单元测试框架,
如xUnit、NUnit、MbUnit等等,就可以在下拉列表中看到了。 按照下图的设置创建新的ASP.NET MVC 4项目,点击OK按钮。
http://www.EntLib.com
11
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
这样将创建一个包含两个项目的solution(解决方案),一个是web应用程序,另外一个单元测试项目。
MVC 应用程序的结构
在我们使用Visual Studio 2012创建一个新的ASP.NET MVC应用程序时,它将自动添加一些文件和目录到项目中,如下图所示。通过Internet应用程序模板创建的ASP.NET MVC项目有9个一级目录。
http://www.EntLib.com
12
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
默认一级目录结构:
/Controllers – 存放负责处理URL请求的控制器类; /Models – 存放表示和操纵数据以及业务对象的类; /Views – 存放负责呈现输出内容的UI模板文件; /Scripts – 存放JavaScript 类库文件和脚本文件.js; /Images – 存放网站中使用到的图像文件;
/Content – 存放CSS和其他非Scripts和图像的网站内容; /Filters – 存放过滤器代码,过滤器是一个高级特性; /App_Data – 存放可读写数据文件;
/App_Start – 存放功能配置代码,如Routing、Bundling、Web API等等。
这个只是ASP.NET MVC 的默认项目结构,开发人员可以根据实际需要进行调整。如在大
http://www.EntLib.com
13
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
型应用程序中,一般使用多个项目,如将数据模型类存放在一个独立的Class Library项目中,让项目更易于管理。然而,默认的项目结构提供了一个很好的默认目录约定,使应用程序的关注点很清晰。
除了默认的目录结构之外,Visual Studio 也创建了一些默认的文件。如在/Controllers目录下,有两个控制器(Controller)类,分别为HomeController和AccountController。在/Views目录下,有三个子目录,分别为/Account、/Home和/Shared,以及一些模板文件。还有/Content和/Scripts目录,Site.css文件用来设置站点的HTML样式,JavaScript类库则让应用程序支持jQuery应用。在MvcMusticStore.Tests项目中,包含了对Controller类的单元测试。
如有兴趣,你可以通过Visual Studio 2012 运行一下我们刚刚创建的MVC应用程序,效果如下所示,都是模板默认创建的功能和页面:
http://www.EntLib.com
14
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
ASP.NET MVC 和约定
默认情况下,ASP.NET MVC应用程序非常依赖于约定。如ASP.NET MVC在
\\Views\\Controller-Name目录下查找视图模板文件。MVC是围绕一些默认约定来设计的,在需要的时候可以覆盖,这个概念通常称为约定优于配置(convention over configuration)。
ASP.NET MVC 依赖于使应用程序工作的三个核心目录: Controllers Models Views
我们不必在web.config文件中设置这些目录,按照约定这些目录应该存在于项目中。ASP.NET MVC的约定是非常好直接的,下面是应用程序结构所期望的约定: 每一个Controller的类文件,以Controller结束,如ProductController、
HomeController等等,并且存放在Controllers目录中; 应用程序中有一个唯一的Views目录,存放所有的视图文件;
控制器使用的视图存放在Views主目录下的控制器类名(去除Controller后缀)下的
子目录中。如ProductController控制器的视图存放在/Views/Product目录中。 所有可重用的UI元素存放在相似的目录结构中,但是在/Views/Shared目录中。
http://www.EntLib.com
15
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
第二章 控制器(Controller)
在ASP.NET MVC中,每一个Web请求都路由到控制器中的一个方法或操作上,控制器负责解释这些请求,并操作数据模型,然后选择一个视图,响应用户的请求。
Home Controller控制器
在开始编写代码之前,我们打开之前创建的项目中Home Controller控制器。在使用Internet应用程序模板创建的MVC项目中包含了两个控制器类: HomeController – 负责网站的首页,about页面和contact页面; AccountController – 负责账号相关的情况,如login和账号注册等等; 在Visual Studio 项目中,展开/Controllers目录,打开HomeController.cs文件。
http://www.EntLib.com
16
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
HomeController 继承Controller 基类,其中Index方法负责处理浏览网站首页的请求。 下面我们修改Index方法的代码,更改ViewBag.Message 赋值的字符串,更改后代码如下所示:
using System;
using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc;
namespace MvcMusicStore.Controllers {
public class HomeController : Controller {
public ActionResult Index() {
ViewBag.Message = \"欢迎光临 EntLib.com 开源电子商务平台!\";
return View(); }
public ActionResult About() {
ViewBag.Message = \"你的应用程序说明页。\";
return View(); }
public ActionResult Contact() {
ViewBag.Message = \"你的联系方式页。\";
return View(); } } }
点击 F5键,或者使用工具条上的运行按钮,Visual Studio将编译应用程序,并在IIS Express中启动站点。
http://www.EntLib.com
17
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
MVC 应用程序在浏览器中运行效果如下所示:
Visual Studio 2012包含了IIS Express,是IIS的一个本地开发版本,可在一个随机可用的端口号运行我们的网站。
Visual Studio 2010和之前版本使用Visual Studio Development Server(也称为
http://www.EntLib.com
18
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
Cassini),而不是IIS Express。尽管Development Server和IIS 相似,但是IIS 7.5 Express实际上IIS为开发目的进行优化的版本。
我们也可以在项目属性窗口的Web标签页查看或调整开发服务器的设置。
编写第一个控制器 创建新的控制器
右击Solution Explorer中的Controllers文件夹,选择添加>控制器…菜单项。
http://www.EntLib.com
19
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
在弹出的添加控制器窗口中,控制器名称设置为HelloWorldController,模板选择空MVC控制器,如下图所示。
点击添加按钮。在解决方案资源管理器中添加一个新的文件HelloWorldController.cs,该文件已经显示在IDE中。
http://www.EntLib.com
20
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
编写Action方法
更新HelloWorldController.cs文件的代码如下所示。
using System;
using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc;
namespace MvcMovie.Controllers {
public class HelloWorldController : Controller { //
// GET: /HelloWorld/
public string Index() {
return \"This is my default action...\"; }
//
// GET: /HelloWorld/Welcome/
public string Welcome() {
return \"This is the Welcome action method...\"; }
http://www.EntLib.com
21
EntLib.com 团队编写 } }
一步一步学习ASP.NET MVC 编程
上述控制器的方法都返回一个HTML字符串,其中第一个方法是Index。我们现在运行应用程序,在浏览器中浏览/HelloWorld地址。浏览器中运行效果如下所示。该方法直接返回一个字符串。
ASP.NET MVC 根据请求的URL地址调用不同的控制器类和不同的动作方法(Action Method)。ASP.NET MVC 使用的默认URL路由逻辑如下所示: /[Controller]/[ActionName]/[Parameters]
URL 路径的第一部分决定了执行的控制器类,因此/HelloWorld映射到
HelloWorldController类。URL 路径的第二部分决定了要执行类的动作方法,因此/HelloWorld/Index 将执行HelloWorldController类的Index方法。前面我们浏览/HelloWorld地址,默认调用Index方法。这是因为如果没有明确指定动作方法,将调用默认的Index方法。
浏览/HelloWorld/Welcome 路径,调用Welcome方法,并返回字符串This is the Welcome action method...。默认MVC映射为
/[Controller]/[ActionName]/[Parameters]。针对这个URL地址,控制器为HelloWorld,动作方法为Welcome,还没有使用URL地址的[Parameters]部分。
http://www.EntLib.com
22
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
从上面的工作中,我们可得出如下结论:
1. 浏览/HelloWorld/Welcome将执行HelloWorldController类的Welcome方法,不必任何额外的配置。
2. HelloWorldController控制器类继承System.Web.Mvc.Controller基类;
3. 我们使用控制器在浏览器中显示一段文本,没有使用模型(model)和视图(view)。尽管模型和视图在有实际用途的ASP.NET MVC 应用程序中是必不可少的,但控制器是核心部分。每一个Web请求都需要经过控制器,然而某些请求则可不必使用模型和视图。
控制器方法中的参数
现在我们修改前面的代码,从URL地址传入一些参数信息给控制器,如
/HelloWorld/Welcome?name=Rickie&numtimes=5。修改Welcome方法,添加两个参数。注意代码中使用了C#可选参数(optional-parameter)功能,表示如果没有传入numTimes参数,该参数将默认为1。
//
// GET: /HelloWorld/Welcome/
public string Welcome(string name, int numTimes = 1) {
return HttpUtility.HtmlEncode(\"Hello \" + name + \NumTimes is: \" + numTimes); }
再次运行应用程序,浏览URL地址/HelloWorld/Welcome?name=Rickie&numtimes=5。
http://www.EntLib.com
23
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
当然,我们也可以对URL地址中name和numtimes输入不同的参数值。ASP.NET MVC 模型绑定系统自动映射URL地址中查询字符串的命名参数给控制器方法中的参数。
控制器动作方法就好像是Web浏览器直接调用控制器中的方法。不过,在一般应用中,控制器通过URL调用,然后执行动作方法,并返回一个视图。
http://www.EntLib.com
24
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
第三章 视图(Views)
视图是应用程序向用户呈现的用户界面,是应用程序的可视化部分。视图引用模型对象,并转换模型数据为良好格式和布局,展示给用户。
分析Home视图
前面我们谈到过,MVC项目中/Views/Home目录下,自动创建了相应的视图文件。按照约定,每一个控制器都有一个视图目录,且名称和控制器的名称一样,但不包括Controller后缀。例如,HomeController对应着/Views/Home视图目录。
同时,在视图目录中,每一个控制器动作方法都有一个视图文件,文件名称和动作方法一样。动作方法通过View方法返回一个ViewResult对象。
public ActionResult Index() {
ViewBag.Message = \"欢迎光临 EntLib.com 开源电子商务平台!\";
return View(); }
控制器动作方法并没有指定视图名称。当视图名称没有指定时,动作方法返回的ViewResult将按照约定来寻找视图。首先在/Views/ControllerName目录查找和动作方法名称一样的视图,针对上面的代码,就是查找/Views/Home/Index.cshtml文件。
当然,ASP.NET MVC的约定可以覆盖。如果我们希望Index方法呈现一个不同的视图,可以传入特定的视图名称。 return View(“Default”);
这样,就会寻找/Views/Home/Default.cshtml文件。当然,在一些情况下,我们也可以指定完整的视图文件路径,使用~波浪符号提供完整视图的完整路径。
http://www.EntLib.com
25
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
return View(\"~/Views/Example/Index.cshtml\");
在使用波浪符号语法时,必须指定视图文件的扩展名,因为这时已经绕开了视图引擎的内部查询机制了。
添加视图
我们将修改HelloWorldController类,使用视图模板文件封装生成HTML响应返回给客户端的过程。
我们将使用ASP.NET MVC 3 引入的Razor视图引擎来创建视图模板文件。基于Razor视图模板文件的后缀为.cshtml,使用C#提供优雅(或精简)的方式创建HTML输出。Razor最小化编写视图模板所需要录入的字符,让Razor视图的开发人员觉得视图代码的编写非常流畅。
目前,Index方法返回一个字符串,且硬编码在控制器类中。我们修改Index方法返回一个View对象,代码如下所示。
//
// GET: /HelloWorld/
public ActionResult Index() {
return View(); }
这样,Index方法是用一个视图模板生成HTML响应返回给浏览器。控制器方法(也称为动作方法-Action Methods),如前面的Index方法,通常返回一个ActionResult(或集成自ActionResult的类),而不是简单的字符串类型。
在项目中,我们添加一个Index方法使用的视图模板。在Index方法中,右击并选择添加
http://www.EntLib.com
26
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
视图…菜单项。
在弹出的添加视图对话框中,保留默认值,点击添加按钮。
在解决方案资源管理器中,可以看到新创建的MvcMovie\\Views\\HelloWorld 文件夹和
http://www.EntLib.com
27
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
MvcMovie\\Views\\HelloWorld\\Index.cshtml文件。
如下是默认创建的Index.cshtml文件。
@{
ViewBag.Title = \"Index\"; }
Index
在
标签下面添加如下HTML脚本:
Hello from our View Template!
完整的MvcMovie\\Views\\HelloWorld\\Index.cshtml 文件如下所示:
@{
ViewBag.Title = \"Index\"; }
http://www.EntLib.com
28
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
Index
Hello from our View Template!
如果使用Visual Studio 2012,在解决方案资源管理器中,右击Index.cshtml文件,选择在Page Inspector中查看菜单项,
另外,也可以运行应用程序,并浏览 /HelloWorld地址。控制器中的Index方法简单运行return View()语句而已,这个表示该方法使用视图模板文件生成响应返回给浏览器。因为我们没有显式指定视图模板文件的名称,ASP.NET MVC默认使用\\Views\\HelloWorld文件夹中Index.cshtml 视图文件。下图显示了视图中硬编码的字符串Hello from our View Template。
http://www.EntLib.com
29
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
还不错。然而,我们发现浏览器的标题显式 – Index-我的ASP.NET MVC应用程序,并且在页面的顶部有一个很大的链接 – 将你的徽标放置在此处。
修改视图和布局页面
首先,我们想修改“将你的徽标放置在此处”的文字,这一文本在每一个页面都是一样的。虽然在应用程序的每一个页面都显示,但实际上在项目中仅在一个地方实现。访问解决方案资源管理器中的/Views/Shared 文件夹,打开_Layout.cshtml 文件。这个文件称为布局页面,在所有其他页面共享使用。
http://www.EntLib.com
30
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
布局模板指定了网站的HTML容器,然后在整个站点多个页面共享。代码中有
@RenderBody() 代码行,RenderBody 是一个占位符,我们创建的所有特定视图将在这里显示。例如,如果我们选择关于链接,Views\\Home\\Abount.cshtml视图将在RenderBody方法中显示。
我们修改布局模板中的站点标题,更新为“电影之家”。
@Html.ActionLink(\"电影之家\", \"Index\", \"Home\")
另外,更新标题文本:
运行应用程序,点击关于链接,可以看到如下效果。我们在布局模板修改一次,站点中的所有页面都显示新的站点标题。
http://www.EntLib.com
31
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
现在,我们修改Index视图的标题。
打开MvcMovie\\Views\\HelloWorld\\Index.cshtml文件,我们修改两个地方:(1)浏览器的标题文本;(2)
元素中文本。我们简单修改这些文本,可以了解哪一部分的代码影响哪一部分的应用程序显示。
@{
ViewBag.Title = \"电影列表\"; }
我的电影列表
Hello from our View Template!
上面的代码设置了ViewBag对象的Title属性。前面我们看到了布局模板(layout template)的源代码,在HTML代码的
节点使用这个值设置运行应用程序,浏览/HelloWorld,发现浏览器标题、页面的主标题和第二级标题都更新了。如果看不到更新,可能是浏览器缓存了内容,可以在浏览器中按Ctrl+F5强制刷新内容。浏览器的标题设置为ViewBag.Title的内容,另外加上在布局文件中的“-电影应用程序”文本。
http://www.EntLib.com
32
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
另外,Index.cshtml视图模板和_Layout.cshtml视图模板合并在一起,以一个单独的HTML响应发送给浏览器。布局模板可以让我们轻松修改布局,然后在整个应用程序中应用。
页面中Hello from our View Template文本信息是在视图中硬编码的,到目前为止,我们只用到了视图(View)和控制器(Controller),还没有使用到模型(Model)。下面我们会演示如何创建数据库,并获取模型数据。
从控制器传递数据给视图
在开始讨论数据库和模型之前,我们先了解从控制器传递数据给视图。控制器类负责响应传入的URL请求。在控制器类中,我们编写代码处理传入的浏览器请求,从数据库中检索数据,并最终决定何种响应返回给浏览器。视图模板(view template)是控制器用来创建并格式化HTML响应返回给浏览器的。
控制器类负责给视图模板提供数据或对象。最佳实践是:视图模板不执行任何业务逻辑或与数据库直接交互。视图模板只和控制器类提供的数据交互。保持关注点分离(separation of
http://www.EntLib.com
33
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
concerns)有助于保持代码的简洁、可测试以及可维护性。
目前,HelloWorlder控制器类中的Welcome动作方法接收name和numTimes参数,并直接输出给浏览器。一般不会让控制器直接返回字符串输出,我们修改控制器使用视图模板。视图模板生成动态响应,这表示需要控制器传入合适的数据给视图,供视图生成响应。我们可通过控制器在ViewBag对象中输入视图模板需要的动态数据(参数),然后视图模板可以访问这些数据。
返回HelloWorldController.cs 文件,修改Welcome方法,添加Message和NumTimes参数值到ViewBag对象中。ViewBag是一个动态对象,表示我们添加任何数据。ViewBag对象并没有定义属性,直到我们添加属性值。ASP.NET MVC 模型绑定系统会自动映射URL地址栏中的查询字符串命名参数(name和numTimes)给方法中定义的参数。完整的HelloWorldController.cs 代码如下所示:
using System;
using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc;
namespace MvcMovie.Controllers {
public class HelloWorldController : Controller { //
// GET: /HelloWorld/
public ActionResult Index() {
return View(); }
public ActionResult Welcome(string name, int numTimes = 1) {
ViewBag.Message = \"Hello \" + name; ViewBag.NumTimes = numTimes;
http://www.EntLib.com
34
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
return View(); } } }
现在ViewBag对象包含了将自动传递给视图的数据。接着,我们添加一个Welcome视图模板。在生成(Build)菜单中,选择生成MvcMovie菜单项,编译MvcMovie项目。 下一步在Welcome方法中,右击选择添加视图…菜单项。
如下是添加视图对话框:
http://www.EntLib.com
35
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
点击添加按钮,接着在新创建的Welcome.cshtml文件中的
元素下面如下代码。我们创建一个循环,根据传入参数多次输出Hello 字符串。完整的Welcome.cshtml代码如下所示。
@{
ViewBag.Title = \"欢迎\"; }
欢迎
- @ViewBag.Message }
@for (int i=0; i < ViewBag.NumTimes; i++) {
运行应用程序,访问如下URL地址:
/HelloWorld/Welcome?name=Rickie&numtimes=5
现在从URL中获取的数据,通过模型绑定传递给控制器。控制器将数据添加奥ViewBag
http://www.EntLib.com
36
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
对象中,并传递给对象给视图,接着视图以HTML形式显示数据给用户。
在上面的示例中,我们使用ViewBag对象从控制器传递数据给视图。在本教程的后面部分,我们将使用视图模型(view model)从控制器传递数据给视图。使用视图模型(view model)传递数据比ViewBag更好一些。
http://www.EntLib.com
37
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
第四章 模型(Model)
本章我们将添加一些类管理数据库中的电影,这些类是ASP.NET MVC 应用程序中的模型(model)部分。
我们将使用.NET框架的数据访问技术,如Entity Framework,来定义和处理这些模型类。Entity Framework(通常简称EF)支持Code First开发模式。Code First允许开发人员编写简单的类创建模型对象(也称为POCO类,plain-old CLR objects),接着基于类创建数据库,实现非常简洁和快速的开发流程。
添加模型类
在解决方案资源管理器中,右击Models文件夹,选择添加>类…菜单项。
输入类名Movie,并添加如下五个属性到Movie类中。
public class Movie {
public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; }
http://www.EntLib.com
38
EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程
public decimal Price { get; set; } }
我们将使用Movie类表示数据库中的电影。每一个Movie对象实例表示数据库表的一行,Movie类的每一个属性将映射到数据表的一列。在相同文件中,添加如下MovieDBContext类:
public class MovieDBContext : DbContext {
public DbSet MovieDBContext类表示Entity Frameworkmovie数据库上下文,负责检索、存储和更新Movie对象实例到数据库中。MovieDBContext继承Entity Framework的DbContext基类。 为了引用DbContext和DbSet类,需要在文件顶部添加如下using 语句: using System.Data.Entity; 完整的Movie.cs文件如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace MvcMovie.Models { public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } } public class MovieDBContext : DbContext { http://www.EntLib.com 39 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 public DbSet 创建连接字符串和SQL Server数据库 创建的MovieDBContext类负责连接数据库,并映射Movie对象到数据库记录。你可能会有一个问题:如何指定连接哪一个数据库呢?我们可以在应用程序的Web.config文件中添加连接字符串信息。 打开应用程序根目录下的Web.config文件(注意:不是Views文件夹下的Web.config文件),添加如下连接字符串到Web.config文件的 绿色背景的信息是我们需要添加到Web.config中的连接字符串,服务器采用本地SQL Server,数据库Movies,用户ID为sa,密码为developer,具体数据库连接根据实际配置进行修改。 接下来,我们将创建一个新的MoviesController类,使用该类显示movie数据,并允许用户创建新的movie列表。 http://www.EntLib.com 40 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 第五章 从控制器中访问模型数据 本章,我们将创建一个新的MoviesController类,编写代码检索movie数据,并使用视图模板在浏览器中显示数据。 在进行下一步之前,首先编译应用程序。 创建MoviesController控制器 右击Controller 文件夹,创建一个新的MoviesController控制器,并输入如下选项: 控制器类名: MoviesController 模板:包含读/写操作和视图的MVC控制器(使用Entity Framework) 模型类:Movie (MvcMovie.Models) 数据上下文类: MovieDBContext (MvcMovie.Models). 视图: Razor (CSHTML) http://www.EntLib.com 41 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 点击添加按钮,Visual Studio创建如下文件和文件夹: 在项目Controllers文件夹中的MoviesController.cs文件; 在项目Views文件夹中的Movies文件夹; 在Views\\Movies文件夹中,创建Create.cshtml、Delete.cshtml、Details.cshtml、Edit.cshtml和Index.cshtml等等文件; ASP.NET MVC 4 自动创建了CRUD(创建、读取、更新和删除)动作方法和视图,自动创建CRUD动作方法和视图的行为也称为构建基架(Scaffolding)。现在,已经创建两个一个完整功能的web应用程序,可以创建、列表、编辑和删除movie记录。 运行应用程序,浏览/Movies 地址。因为应用程序依赖于默认的路由,浏览器请求/Movies地址,将路由给Movies控制器的默认Index动作方法。也就是说,浏览请求/Movies相当于访问/Movies/Index。请求结果是一个空的列表,因为我们还没有添加数据记录。 http://www.EntLib.com 42 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 创建一条新的Movie记录 点击Create New链接,输入电影的相关数据信息,接着点击Create按钮。 点击Create按钮,将提交表单给服务器,在服务器端存储电影信息到数据库中。并接着转 http://www.EntLib.com 43 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 向到/Movies地址,我们可以在列表中查看到新创建的电影记录。 创建更多的电影记录,然后尝试Edit、Details和Delete链接操作,都工作正常。 检查自动生成的代码 打开Controllers\\MoviesController.cs文件,检查自动生成的Index方法。 private MovieDBContext db = new MovieDBContext(); // // GET: /Movies/ public ActionResult Index() { return View(db.Movies.ToList()); } 代码中首先实例化一个movie数据库上下文,然后使用movie数据库上下文执行查询、编辑和删除电影记录的操作。 请求Movies控制器返回数据库中Movies表的所有记录,并传递结果给Index视图。 http://www.EntLib.com 44 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 强类型模型和@model关键字 本教程前面部分,我们了解到控制器可以使用ViewBag对象传递数据给视图模板。ViewBag是一个动态对象,提供了方便的后期绑定(late-bound)的方式来传递信息给视图。 ASP.NET MVC 也提供了传递强类型的对象给视图模板,强类型的方法提供了更好的编译时代码检查,并且在Visual Studio 编辑器中提供了更好的智能提示。Visual Studio中的基架(scaffolding)机制使用这一方法来创建MoviesController 类的动作方法和视图。 打开Controllers\\MoviesController.cs 文件,检查Details方法。 public ActionResult Details(int id = 0) { Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); } 如果找到符合条件的Movie,则将Movie对象实例传递给详细视图。 打开Views\\Movies\\Details.cshtml文件。在创建Movie控制器时,Visual Studio 在Details.cshtml文件的顶部自动包含了如下@model语句: @model MvcMovie.Models.Movie 通过在视图模板顶部引入@model语句,我们可以指定视图需要的对象类型。 @model指令允许在视图中访问控制器传入的模型对象。例如,在Details.cshtml视图模板中,将强类型Model对象的每一个字段传递给HTML辅助方法DisplayNameFor和DisplayFor。Create、Edit方法以及对应的视图模板也是传递的Movie模型对象。 打开Index.cshtml视图模板和MoviesController.cs文件中的Index方法。检查一下代码在Index动作方法中如何创建一个List对象和调用View辅助方法。接着传递Movies list http://www.EntLib.com 45 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 对象给视图: public ActionResult Index() { return View(db.Movies.ToList()); } 当我们创建Movies控制器时,Visual Studio自动在Index.cshtml文件的顶部添加了如下@model语句: @model IEnumerable @model指令可以让我们访问控制器传入的Movie对象列表。例如,在Index.cshtml视图模板中,使用foreach代码对强类型Model对象进行遍历,获取list中的每一个子对象。 @foreach (var item in Model) { @Html.DisplayFor(modelItem => item.Title) @Html.DisplayFor(modelItem => item.ReleaseDate) @Html.DisplayFor(modelItem => item.Genre) @Html.DisplayFor(modelItem => item.Price) @Html.ActionLink(\"Edit\", \"Edit\", new { id=item.ID }) | @Html.ActionLink(\"Details\", \"Details\", new { id=item.ID }) | @Html.ActionLink(\"Delete\", \"Delete\", new { id=item.ID }) 因为Model对象是强类型的(IEnumerable http://www.EntLib.com 46 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 检查SQL Server数据库 Entity Framework Code First检测到连接字符串中Movies数据库不存在,Code First会自动创建数据库。我们可以看看SQL Server的数据库Movies,ASP.NET MVC 应用程序 http://www.EntLib.com 47 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 自动创建的数据库。 我们可以看看Movies表结构是如何映射到前面创建的Movie模型类的。Entity Framework Code First 根据Movie模型类自动创建相应的表结构。 可以进一步查询数据表中的记录: 现在,我们已经创建了数据库和一个简单列表页面显示电影记录。下面,我们将检查剩下的基架代码,并添加SearchIndex动作方法和SearchIndex视图,实现查询电影记录的功能。 http://www.EntLib.com 48 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 检查Edit 方法和Edit 视图 运行应用程序,浏览/Movies地址,将鼠标放置在Edit链接上,可以在左下角看到URL链接地址。 Edit 链接是通过Views\\Movies\\Index.cshtml视图中的Html.ActionLink方法生成的。 @Html.ActionLink(\"Edit\ Html 对象是一个辅助器,通过System.Web.Mvc.WebViewPage基类的属性公开出来。辅助器的ActionLink方法简化动态生成指向控制器动作方法的HTML链接。ActionLink的第一个参数是链接文本,第二个参数是调用的动作方法名称,最后一个参数是匿名对象(anonymous object),生成路由数据。 http://www.EntLib.com 49 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 上图中生成的链接地址为http://localhost:11957/Movies/Edit/2。默认的路由,在 App_Start\\RouteConfig.cs中定义的,使用的URL模型为{controller}/{action}/{id}。因此,ASP.NET MVC将http://localhost:11957/Movies/Edit/2请求转换为对Movies控制器中的Edit动作方法的请求,传入参数ID为2。下面是App_Start\\RouteConfig.cs默认的代码。 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute(\"{resource}.axd/{*pathInfo}\"); routes.MapRoute( name: \"Default\", url: \"{controller}/{action}/{id}\", defaults: new { controller = \"Home\", action = \"Index\", id = UrlParameter.Optional } ); } 我们也可以使用查询字符串传入动作方法的参数,如使用 http://localhost:11957/Movies/Edit?id=2 可以传入参数id=2给Movies控制器的Edit动作方法。 打开Movies控制器类,发现有两个Edit动作方法。 // // GET: /Movies/Edit/5 public ActionResult Edit(int id = 0) { http://www.EntLib.com 50 EntLib.com 团队编写 一步一步学习ASP.NET MVC 编程 Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); } // // POST: /Movies/Edit/5 [HttpPost] public ActionResult Edit(Movie movie) { if (ModelState.IsValid) { db.Entry(movie).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction(\"Index\"); } return View(movie); } 我们注意到第二个Edit动作方法之前添加了HttpPost属性(attribute),这个属性表示重载的Edit方法仅限于POST请求调用。我们也可以再第一个Edit方法之前添加HttpGet属性,但是这个不是必须的,因为这个默认设置。 HttpGet Edit方法接收movie ID参数,使用Entity Framework的Find方法查询movie记录,并返回选择的movie记录给Edit视图。如果调用Edit方法时没有提供参数,ID参数设置了默认值0。如果movie记录没有找到,则返回HttpNotFound。当使用基架(scaffolding)系统创建Edit视图时,它会检查Movie类,并类的每一个属性创建代码呈现 }