65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 架构中控制器类的层次结构

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2014 年 7 月 23 日

CPOL

4分钟阅读

viewsIcon

13862

本文将介绍 ASP.NET MVC 框架中控制器类的层次结构。

引言

无需赘述 MVC 架构在微软 Web 开发平台中的流行程度。我们都知道 MVC 代表模型、视图和控制器,其中控制器充当模型和视图之间的粘合剂。它包含业务逻辑,制定数据和决定调用哪个视图以及向其附加哪些数据。

很好,我们了解了它的功能,并高兴地从“Controller”类派生我们的控制器类并完成我们的工作。我们从未想过为什么存在controller类以及它是如何派生的?在我刚接触 MVC 的时候,我也对此不太在意,但后来开始更多地探索控制器,并发现了controller类庞大的层次结构。在本文中,我们将讨论controller类的层次结构,我们将看到该类是如何从各种基类派生并实现各种接口的。首先,我们将讨论controller类的层次结构,然后我们将看到如何在 MVC 框架中从“Control”类定义我们自己的controller类。那么,让我们开始讨论吧。

IController 位于顶层

可以说,这是controller类的最顶层基接口。该接口非常简单简洁,只包含一个签名。以下是IController接口。

namespace System.Web.Mvc
{
    // Summary:
    //     Defines the methods that are required for a controller.
    public interface IController
    {
        // Summary:
        //     Executes the specified request context.
        //
        // Parameters:
        //   requestContext:
        //     The request context.
        void Execute(RequestContext requestContext);
    }
}

它包含单个签名,需要在其具体实现中实现。控制器位于System.Web.Mvc命名空间内,它是 MVC 框架的主要 DLL。该方法将请求上下文作为参数。

实现 IController 的 ControllerBase 类

这是层次结构的下一层,其中ControllerBase类实现了IController接口。ControllerBase包含六个属性,一个无参数构造函数和三个方法。最流行和最知名的属性ViewDataViewBag在此类中定义,我们可以通过它们将数据从控制器发送到视图。我们可以检查到ViewBag是动态的,它是在 MVC 3 中引入的,而ViewData本质上是Dictionary,我们知道我们需要在ViewData中以键值对的形式存储数据。实际上,ViewBag只是ViewData之上的一个抽象,它们内部使用相同的机制来存储数据。ViewBag提供了动态特性的感觉。其余的功能和属性在注释中进行了描述。在 Visual Studio 中浏览每个类时,您可以获得相同的视图。需要记住的是,它是一个abstract类,我们不能创建它的实例。

// Summary:
    //     Represents the base class for all MVC controllers.
    public abstract class ControllerBase : IController
    {
        // Summary:
        //     Initializes a new instance of the System.Web.Mvc.ControllerBase class.
        protected ControllerBase();

        // Summary:
        //     Gets or sets the controller context.
        //
        // Returns:
        //     The controller context.
        public ControllerContext ControllerContext { get; set; }
        //
        // Summary:
        //     Gets or sets the dictionary for temporary data.
        //
        // Returns:
        //     The dictionary for temporary data.
        public TempDataDictionary TempData { get; set; }
        //
        // Summary:
        //     Gets or sets a value that indicates whether request validation is enabled
        //     for this request.
        //
        // Returns:
        //     true if request validation is enabled for this request; otherwise, false.
        //     The default is true.
        public bool ValidateRequest { get; set; }
        //
        // Summary:
        //     Gets or sets the value provider for the controller.
        //
        // Returns:
        //     The value provider for the controller.
        public IValueProvider ValueProvider { get; set; }
        //
        // Summary:
        //     Gets the dynamic view data dictionary.
        //
        // Returns:
        //     The dynamic view data dictionary.
        [Dynamic]
        public dynamic ViewBag { get; }
        //
        // Summary:
        //     Gets or sets the dictionary for view data.
        //
        // Returns:
        //     The dictionary for the view data.
        public ViewDataDictionary ViewData { get; set; }

        // Summary:
        //     Executes the specified request context.
        //
        // Parameters:
        //   requestContext:
        //     The request context.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     The requestContext parameter is null.
        protected virtual void Execute(RequestContext requestContext);
        //
        // Summary:
        //     Executes the request.
        protected abstract void ExecuteCore();
        //
        // Summary:
        //     Initializes the specified request context.
        //
        // Parameters:
        //   requestContext:
        //     The request context.
        protected virtual void Initialize(RequestContext requestContext);
    }

Controller 实现 IController 和 ControllerBase 以及更多其他内容

是的,我们将看到Controller类实现了IController并从ControllerBase以及更多其他类派生。以下是实现信息。Controller类也是abstract类,因此我们不能创建它的实例。实际上,Controller类包含许多方法和属性。在本文中,我们不打算讨论它们;我们只了解 ASP.NET MVC 中Controller类的层次结构。

public abstract class Controller: ControllerBase, IActionFilter, 
IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, 
IResultFilter, IAsyncController, IController, IAsyncManagerContainer

因此,我们看到Controller类正在实现许多其他接口,这些接口包含各种有用的函数来正确地完成控制器的操作。例如,IDisposable接口包含一个与在创建后处理controller对象相关的方法,并且实现了各种与过滤器相关的接口以在控制器级别实现过滤器。

最后,定义我们自己的控制器类

这是层次结构的最后阶段。在这里,我们可以定义我们自己的控制器,它将从Controller类派生。这种层次结构的优点是,我们获得了现成的产品和工具,可以立即开始操作。由于我们正在从Library中的Controller类派生我们自己的Controller类,因此我们能够使用已经在Controller类和BaseController类中实现的所有函数和属性。以下是从Controller类派生我们自己的controller类的方法。

MyController : Controller
{
}

现在,您可能会想到,为什么不从BaseController定义我们自己的controller类,或者为什么不在我们自己的controller类中手动实现所有这些接口呢?从技术上讲,可以采用相同的方法来定义control类,让我们来看一下。在这个例子中,我们从ControllerBase派生了我们的controller类,并尝试运行应用程序。在我们执行控制器之前,ExecuteCore()将被执行,由于我们没有实现它的实现,它将抛出一个异常,但是我们总是可以这样做,因为我们知道 MVC 是一个开源应用程序。

ExecuteCore()执行完毕后,它将执行Hello()操作。因此,优点是微软已经为我们定义了这些内容,我们只需要使用它即可。

要点

如果您是 MVC 框架的新手,那么您可能会想,为什么我们的Controller类以“Controller”后缀结尾?该后缀是强制性的,否则它将不会被激活。我希望在另一篇文章中讨论这个事实。

© . All rights reserved.