首页 > 代码库 > 《音乐商店》第3集:控制器
《音乐商店》第3集:控制器
在典型的 Web 应用中,用户请求的 URL 地址通常映射到保存在网站中的文件上,例如,当用户请求 /Products.aspx 的时候,或者 /Products.php 的时候,很可能是在通过处理 Products.aspx 或者 Products.php 文件来完成任务。
ASP.NET MVC 的处理方式则不同,它没有映射到文件上,相反,将这些 URL 地址映射到类的方法上,这些类被称为“控制器”,控制器用来接受 HTTP 请求,处理用户的输入,获取或者保存数据,其中的处理方法称为 Action,然后将回应发送到客户端,可能是显示了一个 HTML 的网页,下载一个文件,重定向到另外一个地址等等。
一、默认的路由配置
在新创建的项目中,打开 Global.asax.cs 文件,可以看到如下的代码。
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Routing;namespace MvcMusicStore{ // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明, // 请访问 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); } // 一般用来进行网站的初始化 protected void Application_Start() { System.Data.Entity.Database.SetInitializer(new MvcMusicStore.Models.SampleData()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } }}
其中 RegisterRoutes 方法注册了默认的路由配置,在方法中的 routes.MapRoute 语句中,请求地址将会被看成三个部分组成,{controller}/{action}/{id},第一部分称为控制器,如果没有提供的话,默认为 Home, 第二部分称为 Action 方法,如果没有提供的话,默认为 Index, 第三部分称为 id, 通常用来提供数据的标识,没有默认值。这样,当请求 / 地址的时候,系统将会把请求映射到名为 Home 的控制器进行处理,调用其中名为 Index 的方法处理请求。
二、增加 StoreController
增加一个控制器,可以用来浏览我们的音乐商店,我们的商店控制器将要支持三个场景:
- 列出商店中的唱片的分类
- 浏览商店中某个分类中的唱片列表
- 显示特定唱片的详细信息
我们从增加一个新的 StoreController 开始,在 Controllers 文件夹上右健,选择“添加”,“控制器”。新的 StoreController 控制器中已经包含了 Index 方法,我们使用这个方法来实现列出所有分类的列表,我们还会再增加两个额外的方法来实现其他的场景:浏览和明细。
这些包含在控制器中的方法,我们称为控制器中的 Action,这些 Action 的作用就是处理请求,然后返回对请求的处理结果。
对于我们的 StoreController ,首先让 Index 这个 Action 返回一个“Hello” 串,然后,增加两个方法:Browse() 和 Detials()
//// GET: /Store/Browse?genre=?Discopublic string Browse(string genre){ string message = HttpUtility.HtmlEncode("Store.Browse, Genre = " + genre); return message;}
重新运行程序,现在已经可以访问这些地址了。
- /Store
- /Store/Browse
- /Store/Details
太棒了,但是现在仅仅能够返回一些常量的字符串,让我们将它们变成动态的,我们从 URL 中获取一些信息,然后把他们显示在返回的页面中。
首先,修改我们的 Browse 这个 Action,使得它可以从 URL 地址中获取查询信息,为方法增加一个名为“genre” 的字符串类型参数,当我们这样做的时候,ASP.NET MVC 就会自动把任何名为 genre 的请求参数的值赋予这个参数。
// // 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>.
现在,我们在浏览器中访问一下:/Store/Browse?Genre=Disco
下一步,我们处理 Details 这个 Action,使它能够处理名为 ID 的整数类型参数。这次,我们不再在请求参数中传递这个整数,而是嵌在请求的 URL 地址中。例如:/Store/Details/5。
在 ASP.NET MVC 中,我们可以轻易地完成这个任务而不需要配置任何东西,ASP.NET MVC 默认的路由约定会将跟在 Action 方法之后的部分看作名为 ID 的参数的值,如果你的 Action 方法有一个名为 ID 的参数,那么,ASP.NeT MVC 就会自动将这部分作为参数传送给 Action 方法,需要注意的是,MVC 可以帮助你完成数据类型之间的转换,所以,地址的第三部分一定要可以转换为整数。
// // GET: /Store/Details/5 public string Details(int id) { string message = "Store.Details, ID = " + id; return message; }
再次运行程序访问/Store/Details/5
总结一下我们完成的任务:
- 创建了一个 ASP.NET MVC 项目
- 讨论了基本的项目文件夹
- 学习了如何运行开发服务器
- 创建了两个控制器 HomeController 和 StoreController
- 为控制器增加了 Action 方法。
《音乐商店》第3集:控制器