ASP.NET MVC框架中的控制器与控制器行为

来源:互联网 发布:unity3d 网页插件 编辑:程序博客网 时间:2024/05/10 09:58

转自itpub.net网http://space.itpub.net/14466241/spacelist-blog

作者 朱先忠

一、简介

ASP.NET MVC框架把URL映射到作为控制器引用的类。控制器处理到来的请求,处理用户输入和交互,并且执行适当的应用程序逻辑。典型地,一个控制器类调用一个单独的视图组件生成相应于请求的HTML标记。

概括来看,ASP.NET为基于MVC框架进行开发提供了下列类型:

  • <!--[if !supportLists]--><!--[endif]-->IController—这种类型定义了控制器类的一种契约。
  • <!--[if !supportLists]-->Controller—这是一个基控制器类,用于提供一般性的MVC处理。

进一步分析来看,这个Controller基类负责处理下列几件事情:

  • <!--[if !supportLists]--><!--[endif]-->定位要调用的行为方法并且验证它们的确可以被调用。
  • <!--[if !supportLists]--><!--[endif]-->取得用作行为方法的参数的值。
  • <!--[if !supportLists]-->处理所有的在行为执行期间可能发生的错误。
  • <!--[if !supportLists]--><!--[endif]-->提供默认的WebFormViewFactory类以生成ASP.NET页面类型(视图)。

注意,为了确保安全地访问控制器与控制器行为,你可以使用PrincipalPermissionAttribute类。

下列示例展示了一个控制器类。这个控制器类中提供了行为方法,行为方法参数,还有一个视图渲染方法。

namespace MvcApplication.Controllers

{

   public class HomeController : Controller

   {

       public void Index()

       {

           RenderView("Index");

       }

       public void About()

       {

           ViewData["CompanyName"] = "Contoso";

           RenderView("About");

       }

   }

}

 

二、行为方法

行为方法是在控制器中定义的。典型地,行为中针对每一个用户交互都创建一个一一对应的映射。用户交互的例子包括在浏览器中输入一个URL,点击一个链接,以及提交一个表单,等等。每一个这类的用户交互都会导致把一个请求发送到服务器。在上述所发生的每一种情况下,请求URL中都会包括相应的信息以便MVC框架用以调用一个相应的行为方法。

例如,当用户在浏览器输入一个URL时,MVC应用程序使用定义于Global.asax文件中的路由规则来分析该URL并决定指向控制器的路径。然后,该控制器定位适当的行为方法来处理这一请求。根据具体需要,控制器中可以定义尽可能多的行为方法。

在不使用MVC框架的ASP.NET应用程序中,用户交互都是围绕着页面以及引发和处理这些页面的事件进行组织的。相比之下,使用ASP.NET MVC应用程序的用户交互则围绕控制器及其中的行为方法进行组织。

默认情况下,一个请求URL被当作一个子路径进行解析,其中包括控制器名,后面跟着行为名。例如,如果一个用户输入URLhttp://contoso.com/MyWebSite/Products/Categories,则子路径为“/Products/Categories”。默认的路由规则总是把“Products”作为控制器名,而把“Categories”作为行为名。于是,该路由规则将调用Products控制器的Categories方法来处理该请求.如果URL以“/Products/Detail/5结尾,则默认的路由规则把“Detail”作为行为名,并且调用Products控制器的Detail方法来处理请求。默认情况下,URL中的“5”将被传递为Detail方法的一个参数。

下面的代码片断展示了仅包含一个控制器行为的控制器类:

public class CatalogController : Controller

{

   public void Hello()

   {

       RenderView("HelloWorld");

   }

}

所有的控制器类必须都必须以“Controller”后缀命名,并且所有的控制器类都必须派生自基类Controller

MVC框架认为所有的public方法都是行为方法。因此,如果你的控制器类包含一个不是行为方法的public方法,那么你必须使用NonActionAttribute属性标记它。

三、行为方法参数

默认情况下,行为方法的参数值将从请求的数据集合中检索。该数据集合中包括了相应于表单数据,查询字符串值以及cookie值的名字/值。

Controller基类将基于RouteData实例和表单数据来定位行为方法并决定行为方法的任何参数值。如果不能分析该参数值,并且如果参数类型是一个引用类型或一个nullable值类型,那么将把null作为参数值。否则,抛出一个异常。

在控制器类行为方法内部可以使用多种方式访问URL参数值。Controller基类暴露了一组RequestResponse对象,它们可以在一个行为方法内部被访问。这些对象具有与ASP.NET中的HttpRequestHttpResponse对象相同的语义。然而,一个重要的区别是,控制器类的RequestResponse对象都是基于System.Web.IHttpRequestSystem.Web.IHttpResponse接口,而不是封装(sealed)类型的类。这样的接口便于更容易地创建mock对象,从而使得更易于创建控制器类的单元测试。

下列示例展示如何使用请求对象从Detail行为方法内部来检索一个查询名字为id的字符串值。

public void Detail()

{

   int id = Convert.ToInt32(Request["id"]);

}

四、自动映射行为方法参数

ASP.NET MVC框架可以自动地把URL参数值映射为行为方法的参数值。默认情况下,如果一个行为方法中包含一个参数,那么MVC框架将分析到来的请求数据并决定该请求是否包含一个含有相同名字的HTTP请求值。如果包含的话,则该请求值会被自动地传递给该行为方法。

下面的示例展示了前面示例的一个修改版本。在这个修改版本中,假定该id参数被映射为请求中的一个名字也是id的值。因为这是通过自动映射实现的,所以行为方法中不必专门进行编码来取得请求中的参数值;因此,使用起来十分方便。

public void Detail(int id)

{

   ViewData["DetailInfo"] = id;

   RenderView("Detail");

}

你还可以把参数值嵌入为URL的一个部分而不是以查询字符串值的方式传递。例如,不是使用带有例如查询字符串/Products/Detail?id=3这样的URL,而是使用一个像/Products/Detail/3这样的URL

默认的路由映射规则格式为/[controller]/[action]/[id]。如果在URL中在控制器和行为名称后面存在一个URL子路径,那么它会被作为一个名字为id的参数对待,并且被自动地作为一个参数值传递给行为方法.

此外,MVC框架还支持行为方法中使用可选的参数。对于控制器行为方法而言,MVC框架中的可选参数是使用nullable类型参数进行处理的。例如,如果一个方法以一个日期作为查询字符串的一部分,但是如果没有提供查询字符串参数的话,默认地将使用今天的日期。例如,你可以使用下列代码:

public void ShowArticles(DateTime date)

{

   if(!date.HasValue)

   {

       date = DateTime.Now;

   }

   //……

}

如果请求中包括一个date参数值,那么这个值将被传递给ShowArticles方法。如果请求中没有为这个参数提供一个值,那么该参数将是null,并且可以采取任何必要的措施设计控制器来处理该丢失的参数。

五、处理未知的行为名称

基类Controller通过调用它的HandleUnknownAction方法来处理一个未知的行为名字。基类Controller的实现中将返回一个HTTP 404状态代码.

对于在URL中引用但是并不是响应于实际的行为方法的那些行为方法,可以为它们配置默认的处理方式。下列示例给出了一种方法以重载HandleUnknownError方法并且把一个请求重定向到一个搜索页面。

public void override HandleUnknownError(string action) {

   //重定向到一个搜索页面,此时未知的行为是搜索查询

   //根据调用ShouldShowSearch()方法的结果决定何时显示搜索页面

   if (ShouldShowSearch(action) == true)

   {

       RedirectToAction("search", action );

       return;

   }

   base.HandleUnknownError(action);

}

 

原创粉丝点击