第5章 控制器 本章导读 控制器是ASP.NETMVC的框架核心,负责控制客户端与服务端的交互,协调Model 与View之间数据的传递。本章将学习如何根据需求选择恰当的模板创建控制器、如何选 择控制器中的动作属性、如何确定控制器中动作的返回值等ASP. NETMVC应用程序开发 的核心内容。 本章要点 .控制器创建 .控制器模板 .控制器的动作选择器 .控制器的ActionResult 5.控制器简介 1 控制器(Controler) NETMVC的框架核心, 作为ASP.主要扮演中转和中介两大角色。 中转作用体现在控制器实现承上启下的作用,根据用户输入执行响应(Action),同时在行为 中调用模型的业务逻辑,返回给用户视图(View)。中介角色体现在分离视图和模型,让视 图和模型各司其职,由控制器实现二者的交互。 控制器在MVC架构中的作用如图5. 1所示。 图5. 1 控制器在MVC架构中的作用 1 20 5.2 控制器的基本使用 5.2.1 控制器的基本内容 本节使用第1章创建的MVC5网站,详细讲解控制器的基本结构,所有的控制器都存放 在网站根目录的Controllers文件夹中,并且以“控制器名称+Controller”命名,如图5.2所示。 图5.2 控制器存放目录 控制器是继承自System.Web.Mvc.Controller的C# 类,Controller是内置的控制器基 类。控制器中的每个公有方法都称为一个动作,可以通过对应的URL从Web调用其来执 行,所有的Controller都需要满足如下基本约束。 (1)Controller类必须为公有类型。 (2)控制器名称必须以Controller结尾。 (3)必须继承自ASP.NET MVC内置的Controller基类,或实现IController接口。 打开Home控制器对应的HomeController.cs文件,代码如下。 public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的ASP.NET MVC 应用程序。"; return View(); 视频讲解 1 21 } public ActionResult About() { ViewBag.Message = "你的应用程序说明页。"; return View(); } public ActionResult Contact() { ViewBag.Message = "你的联系方式页。"; return View(); } } HomeController类中包含三个公有方法(PublicMethod),即三个动作(Action),通过 方法可以接收客户端传来的要求,响应视图(View),方法的返回值类型(ActionResult)在后 续章节中介绍。控制器中所有非公有的方法,如private或protected类型的方法都不会被 视为动作。 5.2.2 控制器的创建 5.2.1节针对以模板项目创建的控制器进行了说明,除此以外也可以根据需要新建控制 器。接下来讲解如何在Controller文件内添加新的控制器。 【例5-1】 在D盘ASP.NET MVC应用程序目录中创建chapter5子目录,将其作为网 站根目录,创建一个名为example5-1 的MVC 项目,在Controllers 文件夹中新建 HelloController控制器,添加基本视图,练习控制器的简单应用。 步骤1:在“解决方案资源管理器”中右击Controllers文件夹,选择“添加”→“控制器” 选项,如图5.3所示。 图5.3 添加控制器 视频讲解 1 22 步骤2:在“添加基架”对话框中选择“MVC5控制器-空”模板,单击“添加”按钮,如 图5.4所示。其他模板将在下一小节介绍。 图5.4 添加控制器 步骤3:在“添加控制器”对话框中修改控制器名称为HelloController,单击“添加”按 钮,如图5.5所示。 图5.5 输入控制器名称 步骤4:在“解决方案资源管理器”的Controllers文件夹下,新增HelloController.cs文 件,Views文件夹下新增空文件夹Hello,用于存放Hello控制器中各Action,对应的界面如 图5.6所示。 步骤5:打开HelloController.cs文件,代码如下。 public class HelloController : Controller { // GET: Hello public ActionResult Index() { return View(); } } 图5. 6 控制器 使用“MVC5控制器-空”模板创建的Helo控制器初始时只包含一个默认的无参 Index动作。 步骤6:为Index创建对应视图,在Index方法上右击,内容菜单中选择“添加视图”选 项,如图5. 7所示。 图5. 7 控制器添加视图 步骤7:在“添加视图”对话框中修改“视图名称”为Index,“模板”选择Empty,单击“添 加”按钮,8所示。更多视图模板将在第6章中介绍。 如图5. 步骤8:在View/Helo文件夹内, dx.stl视图文件,9所示。 s新增了Inechm如图5. 步骤9:打开Indx.stml文件,修改代码如下 。 ech 123 1 24 图5.8 视图选择模板 图5.9 视图文件 @{ ViewBag.Title = "Index"; }

Hello Index

步骤10:运行网站,输入网址“http://localhost:XXXX/Hello/Index”,网站运行效果 如图5.10所示。 注意: http://localhost:XXXX/Hello/Index网址中,XXXX代表端口号,请自行替换为读者 计算机实际端口号。 1 25 图5.10 网站运行页面 5.2.3 控制器的读写模板 在例5-1第2步的“添加基架”对话框中,可以为待创建的控制器进行模板选择,示例中 使用的是“MVC5控制器-空”模板,除此以外,ASP.NET MVC5中还支持“包含读/写操作 的MVC5控制器”“包视图的MVC5控制器(使用EntityFramework)”等模板,恰当的模 板选择可以极大地提高后续开发效率。接下来对最常用的“包含读/写操作的MVC5控制 器”模板进行简单介绍。 在例5-1的第2步选择“包含读/写操作的MVC5控制器”模板,则创建的控制器中除 了Index动作外,还会包含Details、Create、Edit、Delete等动作。其中,Create、Edit、Delete 都包含[HttpGet]和[HttpPost]修饰的两个动作,在这些方法上适当添加代码就可以实现 读写等相关的操作。 初始默认代码如下。 namespace WebApplication3.Controllers { public class HelloController : Controller { // GET: Hello public ActionResult Index() { return View(); 1 26 } // GET: Hello/Details/5 public ActionResult Details(int id) { return View(); } // GET: Hello/Create public ActionResult Create() { return View(); } // POST: Default/Create [HttpPost] public ActionResult Create(FormCollection collection) { try { // TODO: Add insert logic here return RedirectToAction("Index"); } catch { return View(); } } // GET: Hello/Edit/5 public ActionResult Edit(int id) { return View(); } // POST: Hello/Edit/5 [HttpPost] public ActionResult Edit(int id, FormCollection collection) { try { // TODO: Add update logic here return RedirectToAction("Index"); } catch { return View(); } 1 27 } // GET: Hello/Delete/5 public ActionResult Delete(int id) { return View(); } // POST: Hello/Delete/5 [HttpPost] public ActionResult Delete(int id, FormCollection collection) { try { // TODO: Add delete logic here return RedirectToAction("Index"); } catch { return View(); } } } 5.3 动作选择器 动作选择器也称为动作方法选择器(ActionMethodSelector),是应用于动作方法上的 属性,用于响应控制器对方法的调用,通过路由引擎选择正确的操作方法来处理特定的请 求。动作方法选择器使用较多的是动作名称(ActionName)、无为动作(NonAction)和动作 方法限定(ActionVerbs)三种属性。 5.3.1 动作名称属性 当ActionInvoker选取Controller中的Action时,默认会应用反射机制找到相同名字 的方法,这个过程就是动作名称选择器运行的过程。除此也可以使用“动作名称”的属性,通 过[ActionName]属性设置动作方法的别名。选择器将根据修改后的名称来决定方法的调 用,选择适当的Action。 [ActionName]基本语法如下。 [ActionName("newActionName")] newActionName是开发人员为方法设置的别名,选择时不区分动作名称的大小写。 视频讲解 1 28 【例5-2】 在chapter5目录中创建一个名为example5-2的项目,创建MVC页面,在控 制器中为Action添加ActionName属性,在页面中测试该动作名称属性。 步骤1:在Home控制器中添加GetDateTimeView方法,编辑代码如下。 [ActionName("GetDate")] public string GetDateTimeView() { return DateTime.Now.ToLongDateString(); } 步骤2:创建对应的GetDateTimeView.cshtml页面。 步骤3:使用http://localhost:55566/Home/GetDate访问页面,如图5.11所示。 图5.11 ActionName属性访问实例 方法中添加了[ActionName("GetDate")]属性,所以访问GetDateTimeView 动作,需 要使用路由http://localhost:55566/Home/GetDate,此时ASP.NET MVC 会去寻找/ Views/Home/GetDateTimeView.cshtml视图页面来运行。 一个Action只可以包含一个ActionName属性,不允许多个方法对应同一个Action名 称,否则在运行请求对应Action时会引发异常。 5.3.2 无为动作属性 NonAction是Action的另一个内置属性,将NonAction属性应用在Controller中的某 个Action上,则ActionInvoker将不会运行该Action。这个特性主要用来保护Controller 中的某些特殊的公开方法不发布到Web上,或是隐藏某些尚未开发完成而又不想删除的 Action,套用这个特性就可以不对外公开该功能。 【例5-3】 创建MVC页面,在控制器中为某一Action添加NonAction属性,在页面中 测试该无为动作属性。 步骤1:编写Action代码如下。 [NonAction] public ActionResult NonAction 测试() { return View(); } 步骤2:创建对应的“NonAction测试.cshtml”页面。 视频讲解