原文:http://quickstarts.asp.net/3-5-extensions/mvc/MVCControllerActions.aspx
介绍
ASP.NET MVC 框架直接映射URL到他们所引用的控制器类中。控制器处理引入的请求,用户的输入和交互,以及执行相应的应用程式和数据逻辑。一个典型的控制器,会呼叫一个分离开的视图为请求生成HTML标记。
注意:
要运行以下代码,你需要ASP.NET 3.5 Extensions预览版。你可以从 ASP.NET Web site中下载。
ASP.NET为了MVC开发提供了以下类型
- IController - 控制器的协议接口
- Controller - 提供一般MVC处理的控制器基类
控制器基类有以下职责:
1、指向对应的方法,以及验证是否有权呼叫
2、获取操作方法所需要的参数
3、执行操作方法期间,处理所有异常。
4、为呈现ASP.NET页面(视图)提供默认的WebFormViewFactory。
注意:
为了安全访问各种各样的控制器和控制器的操作,你可以使用PrincipalPermissionAttribute。
以下是一个控制器类的例子。控制器类包含操作方法,操作方法的参数和呈现视图的方法。
namespace HelloWorld.Controllers {
public class SampleController : Controller {
[ControllerAction]
public void ShowProducts(string category) {
ViewData["category"] = category;
RenderView("Products");
}
[ControllerAction]
public void Index() {
RenderView("HelloWorld");
}
}
}
操作方法(Action Methods)
控制器定义许多操作方法。默认情况下,操作方法与用户的交互拥有一对一的关系。用户的交互距离包括使用URL进入浏览器,点击链接,以及提交表单。这些每个用户交互会产生出一个请求,发送到服务器。在每个情况中,请求的URL都包含MVC框架需要调用操作方法的信息。
举例,当用户输入URL到浏览器,MVC应用程式中定义在Global.asax的用户导航规则会分析URL,决定通往哪个控制器。然后,控制器就会定位适当的方法去处理请求。控制器包裹很多所需要的操作方法。
在没有使用MVC框架的ASP.NET应用程式中,用户的交互都集中在页面,以及触发、处理来自页面的事件。相反,在ASP.NET MVC应用程式中,用户交互集中在控制器和他们的操作方法。
默认情况下,一个请求的URL被解释的字路径包括操作名字的控制器的名称。举例,如果用户输入URL“http://contoso.com/MyWebSite/Products/Categories”,子路径为“/Products/Categories”。默认的导航规则认为“Categories”为操作的名称,以及Products控制器将会调用Categories方法处理请求。如果URL以“/Products/Detail/5”结尾,默认的导航规则认为“Detail”为操作的名称,以及Products控制器将会调用Detail方法处理请求。在URL中的5将会当Detail 方法参数传入。
以下例子展示控制器和控制方法:
public class CatalogController : Controller
{
[ControllerAction]
public void Hello()
{
RenderView("HelloWorld");
}
}
所有的控制器类命名必须以Controller结尾,以及控制器的类必须继承于Controller基类。
操作方法参数
默认情况下,操作方法的参数是来自Request的数据集合。数据集合包括“键-值”数据,包括表单数据,查询字符串、cookie值等。
基于RouteData实例和表单数据,控制器基类定位所要操作的方法,如果方法包括参数,控制器基类会为方法决定相关的参数值。如果参数没有被解析出来,并且同时参数的类型是引用类型或者空的允许空的值类型,null就会被当参数传入。否则,抛出异常。TypeConverter通常用于从URL或表单数据参数中,转换正确的参数类型。
在控制器类的操作类中,有几种方法可以访问URL的参数。控制器的基类有一套可在操作方法方法的公开属性对象“Request”和“Response”。这些对象模拟在ASP.NET已有的 HttpRequest 和 HttpResponse 。然而,一个重要的不同点在于,控制器类的Request和Response对象是继承System.Web.IHttpRequest 和 System.Web.IHttpResponse ,代替以往的封闭类。这个接口可以更方便的创建mock对象,更方便对控制器做单元测试。
以下的例子展示如何在Detail方法内,使用Request对象获取查询字符串名为“id”的值。
[ControllerAction]
public void Detail()
{
int id = Convert.ToInt32(Request["id"]);
}
自动映射操作方法参数
ASP.NET MVC 框架可以为操作方法自动映射URL参数到方法的参数值。默认情况下,如果一个操作方法需要参数,MVC框架会检查请求的数据和决定HTTP请求值中是否有相同参数名称值。如果有,请求值自动会传入到操作方法。
下面的示例是上面例子的变体。在这个变体中,id参数被认为映射到请求的URL也名为id的数据。由于自动的映射,方法中无需拥有任何从Request获取参数的代码,因此代码更简洁。
你也可以使用内嵌参数值到URL中,代替以往的查询字符串用法。举例,以往使用查询字符串链接的URL如“/Products/Detail?id=3”,你可以使用类似以下的URL“ /Products/Detail/3”代替。
默认的导航映射规则格式为/[controller]/[action]/[id]。如果URL的子路径后面接着控制器和操作方法的名称,那么参数的名称就被认为id,它会自动传入操作方法做参数。
MVC框架对方法参数允许可选的参数。在MVC内的可选参数,被处理为可空类型,示例,如果你有一个方法需要一个日期的查询字符串,但你想如果参数为空的时候默认为今天的日期,你可以使用以下的代码:
[ControllerAction]
public void ShowArticles(DateTime date)
{
if(!date.HasValue)
{
date = DateTime.Now;
}
// … additional processing
}
如果请求中包含date的参数,那么就会传递到ShowArticles 方法内。如果请求中没有包括参数值,参数将会为null,控制器无论如何也需要处理这个缺省值。
处理未知方法
控制器基类调用HandleUnknownAction处理了一般情况下的未知方法。默认,方法会返回HTTP 404 状态。
你可以为配置默认的一个方法,处理任何不予实际动作方法通讯的URL。以下例子说明一种方法,重写HandleUnknownError方法,重定向到搜索页。
[ControllerAction]
public void override HandleUnknownError(string action) {
// Redirect to a search page where the unknown action is
// the search query.
if (ShouldShowSearch(action) == true)
{
RedirectToAction("search", new { query = action });
return;
}
base.HandleUnknownError(action);
}