MVC音乐商店 - 第二部分:控制器
首先,来张图,提前了解Mvc的工作原理
传统的web框架,传入Url 通常都是直接映射到到磁盘中相应的文件中。例如,一个类似“/Products.aspx”或“/Products.php”的Url 可能由一个“Products.aspx”或“/Products.php” 文件来处理。
基于Web的MVC架构中,Url 映射到服务器的方式不同。他们不像传统的web框架,Url 映射到磁盘中的文件,而是映射到类中的方法中,映射到文件被替换成映射到类中方法,这些类被叫做“Controllers”(控制器)。这些类负责处理传入的http请求、用户输入、检索和保存数据,并确定把响应返回给客户端(显示HTML,下载文件重定向URL等)。
添加 HomeController
现在就添加一个控制器开始我们的MVC音乐商店,他将处理链接到主页的Url 。我们遵循默认的ASP.NET MVC 命名约定(上一篇有介绍到),新建的类 命名为:HomeController。
找到“解决方案资源管理器”中的“Controllers”文件夹,单击右键,选择“添加 ->控制器”:
这将打开“添加控制器”对话框。将名称改为“HomeController”,然后按“添加”按钮。
这将创建一个新的文件,HomeController.cs,将产生以下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcMusicStore.Controllers { public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { return View(); } } }
尽可能的使用一个简单的返回字符串来替代原来的Index方法,只需要修改两个地方:
- 修改方法的返回类型,由ActionResult改成string
- 修改return语句返回字符串“hello mvc!”
修改后的方法应该是这样的:
public string Index() { return "hello mvc!"; }
运行程序
现在让我们来运行站点,按F5(调试启动)或Crtl+F5(不调试启动),启动之后自动打开新的浏览页,显示如下:
蒽,我们很快的创建了一个新的web站点,添加了3行代码,并且浏览器里也显示了一行文本。这只是开始。
注:程序运行之后,将随机产生一个端口号,该站点运行在 http://localhost:6886/,所以他正在使用6886的端口号。
添加 StoreController
先前,我们已经添加了一个简单的HomeController实现网站的主页,现在,让我们添加另一个控制器,他将实现MVC音乐商店的浏览功能,需要实现以下3个功能:
- 音乐类别列表
- 类别列表下的专辑
- 专辑的详细信息
和上面添加HomeController控制器一样的操作,完成添加StroeController控制器。新增的StroeController.cs里已存在Index方法,我们使用Index方法来实现所有类别的列表页面,我们还将要添加两个方法来实现另外两个功能(类别列表里的专辑、专辑的信息)。
这些方法()在我们的控制器内被称为“Controller Actions”,并且和先前的HomeController.Index()方法一样,他们的工作是响应Url 的请求,确定应该把哪些内容发送回浏览器或用户请求的Url 。
我们修改Index方法,让他返回字符串“Hello MVC Store.Index()”,后面添加的2个方法(Browse()、Details()),也用这样的要求来完成StroeControlle的实现。
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 MVC Store.Index()"; } public string Browse(string genre) { return "Hello MVC Store.Browse()"; } public string Details(int id) { return "Hello MVC Store.Details()"; } } }
再次运行项目,并浏览下列url
- /Store
- /Store/Browse
- /Store/Details
访问这些URL将调用控制器中的动作方法并返回字符串:
不过,这些都只是一些不变的字符串,现在,就把他改成动态的吧,从Url 中获取一些信息输入到页面上。首先,我们将修改Browse方法,我们为该方法添加一个参数—gener,当Browse()被调用时,ASP.NET MVC 会自动去传递一个“gener”的参数。
// // GET: /Store/Browse?genre=Disco public string Browse(string genre) { string message = HttpUtility.HtmlEncode("Store.Browse, Genre = " + genre); return message; }
注: 我们使用 HttpUtility.HtmlEncode 方法来判断用户输入。这可防止用户 使用类似
/Store/Browse?Genre=<script>window.location=’http://hackersite.com’</script>这样的链接来对网站进行注入式的攻击。现在我们来看一下结果
我们下一步将要做的是让Details()读取并显示一个叫"ID"的输入参数。与Browse()方法不同的是,我不会把ID的值作为查询的字符串,而是将他作为Url的一部分,例如:/Store/Details/5。ASP.NET MVC 很容易实现刚才这样的想法,而我们又不用去做配置任何东西,ASP.NET MVC 的默认路由设置是把Url中动作部分看作是一个名叫“ID”的参数。如果,操作方法中有一个名为“ID”的参数,ASP.NET MVC会自动去作为参数传递。
// // GET: /Store/Details/5 public string Details(int id) { string message = "Store.Details, ID = " + id; return message; }
运行程序,浏览/Store/Details/5
现在让我们来回顾下,目前我们做了些什么事情:
- 在VS2010中新建了一个ASP.NET MVC 3 的项目
- 讨论了ASP.NET MVC 3 应用程序的默认目录(约定)
- 学习了如何使用ASP.NET开发服务器里运行的web站点(关于那些程序一跑起来就产生的端口,可以在网上了解)
- 创建了2个控制器类:HomeController和StroeController
- 在控制器中添加了3个方法用来响应Url 的请求,并把结果返回给浏览器。
体会:第二部分主要讲了,怎么在新建好的项目里去添加新的控制器和 在浏览器里访问控制器里相应的方法。
1.新建一个控制器,默认有个返回视图的方法,在文中,先用字符串替代,程序运行之后,该字符串也显示在了浏览器上;
2.控制器里方法名称的约定:只问方法名称,不问方法的参数与返回值(根据1可以看出,默认的Index方法是返回视图,但我们改成返回string,照样行的通);
3.控制器的参数:StroeController控制器里有3个方法(Index/Browse/Details),不同的传参方式,显示也不同,具体原因在方法里面。返回字符串的时候,Browse()方法使用了HttpUtility.HtmlEncode,防止JS注入式攻击。
每篇文章的内容我都有写过一遍:控制器、Action和参数是构成网站Url的三个部分,在地址栏里若不输入控制器的名称,则默认使用HomeController,不提供方法名则默认使用Index方法。参数有两种形式,当接受的参数为字符串时,应该使用HttpUtility.HtmlEncode防止js注入攻击。