控 制 器

●  控制器的角色
●  控制器简史
●  控制器基础

●  示例应用程序:MVC Music Store

1.控制器的角色

      MVC模式中的控制器(Controller)主要负责响应用户的输入,并且在响应时通常会修改模型(Model)。通过这种方式,MVC模式中的控制器主要关注的是应用程序流,输入数据的处理,以及对相关视图(View)输出数据的提供。

      过去的Web 服务器支持对以静态文件存储在服务器磁盘上的HTML页面的访问。随着动态网页的流行,Web服务器也支持由同样存储在服务器磁盘上的动态脚本生成的HTML页面。使用MVC,情况就略有不同。URL告知路由机制去实例化哪个控制器,调用哪个操作方法,并为该方法提供需要的参数。然后由控制器的方法决定使用哪个视图,并随后对该视图进行渲染。

     不是与存储在Web服务器的硬盘上的文件有直接对应关系,而是与控制器类的一个方法有关。ASP.NET  MVC实现对MVC模式中的前端控制器进行了改进,路由子系统在最前面,然后才是控制器。
     理解MVC模式在Web场景中工作原理的一个好方法就是记住:MVC提供的是方法调用的结果,而不是动态生成的(又名脚本)页面。

 

2.控制器简史

     MVC已经出现很长一段时间了——可以追溯到现代Web应用程序时代来临前的几十年。当MVC第一次开发出来的时候,图形用户界面(GUI)才刚刚起步没几年,且在不断演化发展。当时,当用户按下一个按键或单击屏幕时,某个进程将会“听到”他们的动作,这个进程就是控制器。控制器主要负责接收和解释输入,并更新任何需要的数据类(模型),然后通知用户进行了修改或程序更新(视图)。
     在20世纪70年代末和80年代初,Xerox PARC(刚好也是MVC模式诞生的地方)的研究员开始研究GUI的概念,在GUI中用户“工作”在一个虚拟的“桌面”环境中,在这种环境下,用户可以单击和来回拖拽条目。从这里产生了事件驱动编程的思想——根据用户触发的事件(如单击鼠标或是敲击键盘上的按键)来执行程序操作。
     后来,随着GUI逐渐成为规范,MVC模式不完全适合这些新系统这一点变得更加清晰。在这类系统中,由GUI组件本身负责处理用户输入,比如当按下一个按钮时,是该按钮本身响应鼠标单击,而不是控制器。按钮转而将依次通知所有单击的观察者或侦听者它被单击了,相对于MVC模式而言,另一些模式(如模型-视图-表示器Model-View-Presenter,MVP)证明是与这些现代系统更相关的。
     ASP.NET Web Forms是一种基于事件的系统,这在Web应用程序平台中是独一无二的。它拥有一个强大的基于控件并由事件驱动的编程模型,从而为开发人员进行Web开发提供了一个良好的组件化的GUI。当单击一个按钮时,Button控件将会做出响应,并在服务器端引发一个事件以告知它被单击。这种方法的妙处在于它可以让开发人员在更高的抽象级别下编写代码。
     然而,进行更深入的分析会发现开展的很多工作都是在模拟这种组件化的事件驱动。然而本质上,当单击一个按钮时,浏览器将向包含了页面上的控件的状态的服务器提交一个请求,其中控件所在的页面被封装在一个编码的隐藏输入中。在服务器端,为了响应该请求,ASP.NET必须重建整个控件层次结构,然后解释请求,并利用请求的内容去恢复应用程序中当前用户的当前状态。究其本质而言,所有这些都是因为Web是无状态的。使用富客户端的Windows  GUI应用程序时,没必要每当用户单击一个UI小部件时就重建整个屏幕和控件层次结构,因为应用程序保持了原状态,不曾改变。
     对于Web程序而言,用户的应用程序状态实质上是消失的,只不过是后来用户每次单击后都会恢复。虽然这会极大地简化程序,但是以HTML形式出现的用户界面将会从服务器发送到客户端浏览器。这就引发一个问题:“应用程序在哪里?”,对于大多数Web 页面而言,应用程序就在客户端和服务器之间“舞蹈”,每次都维持一个小状态,可能是客户端的一个cookie或是服务器上的一块内存,一切都被小心地设计来掩盖一个小小的“谎言”,这个“谎言”就是Internet和HTTP可以进行有状态的编程。
     当进行Web开发时,对由事件驱动的编程方法的支撑作用将不复存在,并且许多人不愿接受这个虚拟有状态的平台的谎言。鉴于此,业界已经见证了MVC模式的复兴(尽管对其做了一点轻微的改动)。
     下面给出一个这种改动的示例。在传统的MVC模式中,模型可以通过与视图的间接联系来“观察”视图,这就允许模型根据视图的事件来自我调整。对于在Web开发中应用MVC模式而言,当视图被发送到客户端浏览器时,模型通常不在内存当中,所以就不再能观察视图上的事件。
     在Web开发中采用MVC模式,控制器再次走在了前列。应用MVC模式要求Web应用程序中的每一个用户输入只采用请求的方式。例如,在ASP.NET MVC中,每个请求都被路由到控制器的一个方法(又称操作),该控制器全权负责解释这些请求,如果必要的话,还要操纵模型,然后通过响应选择一个视图反馈给用户。 

 

3.控制器基础

     a.简单示例:Home Controller

     在开始实质性地编写代码之前,首先了解一下在一个新的项目中默认都包含哪些内容。使用Internet Application模板创建的项目包含两个控制器类:
     ●  HomeController:负责网站根目录下的“home page”和“about page”。
     ●  AccountController:响应与账户相关的请求,比如登录和账户注册。
     在Visual  Studio 的项目中,展开/Controller文件夹,打开HomeController.cs文件,如图2-7所示。

 图  2-7

     注意这是一个相当简单的类,它继承了Controller基类。HomeController类的Index方
法负责决定当浏览网站首页时触发的事件。下面按照以下步骤对程序进行简单的修改,然
后运行程序。
     (1) 用自己想要的短语替换Index 方法中的“Welcome to ASP.NET MVC!”,比如“I like
cake!”。

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 = "I like cake!";
 
            return View();
          }

          public ActionResult About()
          {
                return View();
          }
      }

     (2) 按下F5键或者使用Debug | Start Debugging菜单项运行程序。Visual Studio编译应
用程序并启动ASP.NET  Web开发服务器。在屏幕的右下角会弹出一个通知框,表明
ASP.NET开发服务器已经启动,通知框中还显示了服务器运行的端口号(如图2-8所示)。

   图  2-8

ASP.NET开发服务器
Visual  Studio包含ASP.NET开发服务器(有时称它的老代号,Cassini),它会在一个随
机的空闲端口上运行您的网站。在图2-8中,网站是在
http://localhost:26641/上运行,因此
它采用的端口号是26641,您运行时的端口号可能与这个不同。本书讨论的URL(比如
/Store/Browse)会跟在端口号后面。假设端口号是26641,那么浏览/Store/Browse 将意味着
是浏览
http://localhost:26641/Store/Browse
注意,在Visual Studio 2010 SP1中,利用IIS 7.5 Express代替开发服务器将会更简单。
尽管开发服务器很像IIS,IIS  7.5  Express实际上是IIS的优化版本,优化后更适合开发。
想更多地了解IIS  7.5  Express,请查阅Scott  Guthrie的博客
http://weblogs.asp.net/scottgu/
7673719.aspx
 
     接下来,会打开一个浏览器窗口,显示刚才输入的内容,如图2-9所示。 


 
图  2-9

      现在已经完成了一个新项目的创建并且还在屏幕上显示了一些短语,接下来通过创建
一个新的控制器来创建一个实际的应用程序。

     b.创建第一个(非常简单的)控制器
     首先创建一个控制器来处理有关浏览音乐目录的URL。这个控制器支持以下三个功能:
          ●  索引页面列出商店里包含的音乐类型。
          ●  单击一个流派,跳转到一个列出该流派下所有音乐专辑的页面。
          ●  单击一个专辑,跳转到一个列出有关该专辑所有信息的页面。 
      1. 创建新控制器
         首先添加一个StoreController类。右击Solution Explorer下的Controllers文件夹,选择Add | Controller菜单项,如图2-10所示。

图  2-10

 

     将控制器命名为StoreController,不要选中“Add action methods for Create, Update, Delete,
and Details scenarios”复选框,如图2-11所示。 
 
图  2-11

 

     2. 编写操作方法 
      新创建的StoreController控制器已经有了一个Index 方法,下面将利用这个方法实现在页面上列出音乐商店里所有歌曲流派的功能。另外,还需要添加两个额外的方法来实现上述的其他两个功能,这两个方法分别是Browse和Details。 
     控制器里的这些方法(Index、Browse和Details)被称为控制器操作。正如上述的HomeController.Index()操作方法那样,控制器操作的工作是响应URL请求,执行合适的操作,并向浏览器或者是单击这个URL的用户做出响应。
想要了解控制器操作是如何工作的,可按照以下步骤操作:
          (1) 将Index()方法的签名改为string(而不是ActionResult),然后将返回值改为“Hello from Store.Index()”,如下所示:
//
//GET: /Store/
public string Index()
{
    return " Hello from Store.Index()" ;
}


          (2) 添加对商店的Browse操作方法,将返回值设为“Hello from Store.Browse()”;添加Details操作方法,将返回值设为“Hello  from  Store.Details()”。控制器StoreController的完整代码如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MvcMusicStore.Controllers
{
   public class StoreController : Controller
   {
       //
       // GET: /Store/
       public string Index()
       {
           return "Hello from Store.Index()";
       }
       //
       // GET: /Store/Browse
       public string Browse()
       {
           return "Hello from Store.Browse()";
       }
       //
       // GET: /Store/Details

       public string Details()
       {
           return "Hello from Store.Details()";
       }
   }
}
          (3) 重新运行项目,然后浏览以下URL:
               ●  /Store
               ●  /Store/Browse
               ●  /Store/Details
          访问这些URL会调用控制器中的操作方法,然后返回响应字符串,如图2-12所示。

图  2-12


     3.  经验总结
          从以上这个快速实验中可以得出以下几个结论:
               ●  不需要做任何额外配置,浏览到/Store/Details就可以使StoreController类中的Details方法得到执行,这就是操作中的路由。 
               ●  尽管是使用Visual Studio工具来创建这个控制器类,但它却是个非常简单的类。能看出一个类是控制器类的仅有方式,就是该类继承自System.Web.Mvc.Controller。 
               ●  已经利用一个控制器在浏览器里显示了文本—— 没有用到模型或视图。尽管在ASP.NET MVC中模型和视图非常有用,但控制器才是真正的核心。每一个请求都必须通过控制器处理,然而其中有些是不需要利用模型和视图的。

 
      c.控制器操作中的参数
     前面的例子写出的是常量字符串。下一步就是让它们通过响应URL传进来的参数动态地执行操作。按照以下步骤来实现:
     (1) 将Browse操作方法修改为检索一个从URL传过来的查询字符串值。可以通过向操作方法中添加一个“genre”参数来实现这个功能。然后,当这个方法被调用时,ASP.NET MVC会自动将名字为“genre”的查询字符串或从表单提交的参数传递给Browse操作方法。//
// GET: /Store/Browse?genre=?Disco
public string Browse(string genre)
{
   string message =
         HttpUtility.HtmlEncode("Store.Browse, Genre = " + genre);
 
   return message;


     HTML编码的用户输入
    利用实用方法HttpUtility.HtmlEncode来预处理用户输入。这能阻止用户向视图中用链接注入JavaScript 代码或HTML标记,比如/Store/Browse?Genre=<script>window.location= 'http://hacker.example.com'</script>。


     (2) 浏览到/Store/Browse?Genre=Disco,结果如图2-13所示。

图  2-13
     这表明控制器操作可以通过将查询字符串作为其操作方法的参数来接收其值。


     (3) 修改Details操作方法使其读取和显示一个名称为ID 的输入参数。不像前面的方法那样把ID 值作为一个查询字符串参数嵌入,这里是将ID 值直接嵌入到URL中,如 /Store/Deatila/5。
     ASP.NET  MVC在不需要任何额外配置的情况下可以很容易地做到这一点。ASP.NET MVC的默认路由约定,就是将操作方法名称后面的URL的这个片段作为名称为ID 的参数。如果操作方法中有名称为ID 的参数,那么ASP.NET MVC将会自动将这个URL片段作为参数传递过来。
//
// GET: /Store/Details/5
public string Details(int id)
{
   string message = "Store.Details, ID = " + id;
 
   return message;
}

     (4) 运行应用程序,浏览/Store/Details/5,结果如图2-14所示。 
 
图  2-14 
    

     像前面的示例演示的那样,控制器操作感觉就好像是Web浏览器直接调用控制器类中的方法。类、方法和参数都被具体化为URL中的特定路径片段或查询字符串,结果就是一个返回给浏览器的字符串。这就进行了极大的简化,而忽略了下面这些细节:
         ●  路由将URL映射到操作的方式。
         ●  将视图作为模板生成向浏览器返回的字符串(通常是HTML格式)。
         ●  操作很少返回原始的字符串;它通常返回合适的ActionResult来处理像HTTP状态码和调用视图模板系统这样的事项。

 
     控制器提供了很多自定义和扩展的机会,但是您可能会发现很少能用到这些内容(如果有的话)。在一般应用中,控制器通过URL被调用,然后执行自定义的代码并返回一个视图。 

4.  小结
     控制器是MVC应用程序的“指挥员”,它精心紧密地编排用户、模型对象和视图的交互。同时控制器还负责响应用户输入,操纵正确的模型对象,然后选择合适的视图显示给用户以作为对最初用户输入的响应。
     本章讲解了控制器独立于视图和模型工作的基本原理,讲解了应用程序如何执行代码来响应URL请求,这些都是处理用户界面的必备知识。

 

 

 

 

 

  

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值