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





0/5 (0投票)
本文将介绍 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
包含六个属性,一个无参数构造函数和三个方法。最流行和最知名的属性ViewData
和ViewBag
在此类中定义,我们可以通过它们将数据从控制器发送到视图。我们可以检查到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
”后缀结尾?该后缀是强制性的,否则它将不会被激活。我希望在另一篇文章中讨论这个事实。