设计模式——面向初学者的 MVC 模式示例

已发表: 2016-04-15

它解释了什么是 MVC 模式以及什么是 ASP.NET MVC 框架,它是如何工作的。 还解释了 ASP.NET MVC 页面生命周期和 ASP.NET MVC 功能版本明智。

示例提供了明智的步骤,帮助初学者轻松理解并精通 ASP.NET MVC。

我们都知道许多设计模式并在我们的应用程序中使用它们来实现业务组件和服务,但我们仍然会面临应用程序的问题/挑战。 此外,日常业务需求和优先事项也会发生变化。 如果我们仔细观察我们面临的许多问题、缺陷和挑战,那就是 UI 和表示层。 尽管一些缺陷与业务逻辑和业务规则有关,但我们可能需要在 UI 和表示层中修复它们,因为我们可能在 UI 和表示层中紧密集成业务逻辑。 这背后的原因是我们没有专注于在我们的应用程序中实现正确的设计模式。 让我们一步一步来了解如何在我们的应用程序中实现和使用表示模式。

问题陈述:
  1. 已经在应用程序中使用了不同的模式,但仍然很难维护应用程序。
  2. 使用VS Test、NUnit、MBUnit等测试业务逻辑层,但由于业务逻辑涉及表示层,应用程序中仍然存在一些缺陷。
  3. 在应用程序中使用了表示层、业务逻辑层、数据访问层,但有时仍需要在表示层编写冗余代码来消费或调用其他模块或其他用例。
  4. 当我们对集成模块进行一些更改时,集成缺陷就会被注入。
  5. 缺陷修复和增强需要更多时间来分析表示层逻辑及其集成依赖关系,并导致新缺陷的出现。
  6. 不能选择 ASP.NET MVC,因为 UI 构建起来很复杂。
问题的根本原因:

在表示层,

  1. 页面或表单包含显示应用程序域数据的控件。 用户可以修改数据并提交更改。 该页面检索域数据,处理用户事件,更改页面上的其他控件以响应事件,并提交更改的域数据。 在网页中包含执行这些功能的代码 此外,在需要相同行为的网页之间共享代码也很困难。 类复杂,难以维护,难以测试。
  2. UI 层、UI 逻辑、表示逻辑、业务逻辑紧密耦合。
  3. 表示层负责集成模块或用例。
解决方案:
  1. 选择最佳的表示层模式,将 UI 层、UI 逻辑和表示逻辑以及业务逻辑分离为单独的层,以使代码更易于理解和维护。
  2. 在开发模块或任何用例时启用松散耦合。
  3. 最大化可以通过自动化测试的代码。 (视图很难测试。)
  4. 在需要相同行为的页面之间共享代码。
  5. 将视觉显示和事件处理行为的职责分离到不同的类中,分别命名为视图和演示者或控制器或 ViewModel。
使用演示模式的好处:
  1. 模块化
  2. 测试驱动方法——最大化可以通过自动化测试的代码
  3. 关注点分离
  4. 页面和表单之间的代码共享
  5. 易于维护

有哪些可用的表示层模式?

MVC(模型视图控制器)

MVP (Model View Presenter) 或 (Model Passive View, Supervisor Controller)

MVVM(模型视图 ViewModel)

MVC vs MVP vs MVVM:
  1. Model 和 View 在以上 3 种模式中代表相同?

    是的

  2. Controller、Presenter 和 ViewModel 的用途在以上 3 种模式中都相同吗?

    是的

  3. Model、View with Controller、Presenter、ViewModel的通信和流程是一样的吗?

    ,这就是这三种模式存在的原因。

  4. 这些模式是否替代了 PL(表示层)、BLL(业务逻辑层)和 DAL(数据访问层)

    ,这些模式用于将 UI 和 UI 逻辑与表示逻辑分离并启用松散耦合。

选择最佳的表示层模式:

MVP

  1. 无法通过数据上下文绑定
  2. 复杂的用户界面设计
  3. 最适合 Windows 窗体、ASP.NET Web 窗体和 Sharepoint 应用程序

MVC

  1. 最适合带有简单 UI 的 ASP.NET
  2. 断开模型(视图与所有其他层分离)

注意:这里我不关注 MVC VM(来自 MVC3 的 MVC ViewModel)和具有依赖注入的 ASP.NET MVVM。

MVVM

  1. 可以通过数据上下文绑定
  2. 连接模型
  3. 最适合 WPF 和 Silverlight 应用程序
ASP.NET Web 窗体与 ASP.NET MVC:

ASP.NET Web 窗体

  1. 辐射度
  2. 开发更轻松
  3. 丰富的控件生态系统
  4. 熟悉Windows Forms开发的开发方法
  5. 没有ViewState和没有回发支持

ASP.NET MVC

  1. 关注点清洁分离 (SoC)
  2. 完整的标记控制
  3. 启用 TDD(测试驱动开发)
  4. 启用并轻松制作 REST
  5. 更简单的客户端集成(Javascript)
  6. 多视图引擎(这真的很酷!)
  7. 没有 ViewState 和没有回发支持
  8. 可扩展且支持 WEB 2.0

模型、视图和控制器

  • 模型:模型对象是应用程序中实现应用程序数据域逻辑的部分。 通常,模型对象检索模型状态并将其存储在数据库中。 例如,Product 对象可能会从数据库中检索信息,对其进行操作,然后将更新的信息写回 SQL Server 中的 Products 表。
  • 视图:视图是显示应用程序用户界面 (UI) 的组件。 通常,此 UI 是根据模型数据创建的。 一个示例是 Products 表的编辑视图,它根据 Products 对象的当前状态显示文本框、下拉列表和复选框。
  • 控制器:控制器是处理用户交互、使用模型并最终选择要呈现的显示 UI 的视图的组件。 在 MVC 应用程序中,视图只显示信息; 控制器处理并响应用户输入和交互。 例如,控制器处理查询字符串值,并将这些值传递给模型,模型又使用这些值查询数据库。
ASP.NET MVC 高级页面生命周期?

ASP.NET MVC High Level Page Life Cycle

ASP.NET MVC 低级页面生命周期?

ASP.NET MVC Low Level Page Life Cycle

MVC2.0新特性

1. 模板化助手:

模板化帮助器帮助我们自动将用于编辑和显示的 HTML 元素与数据类型相关联。

例如,当在视图中显示System.DateTime类型的数据时,可以自动呈现 datepicker UI 元素。

这类似于字段模板在 ASP.NET 动态数据中的工作方式。

2.领域:

使用区域 我们可以将一个大型项目组织成多个较小的部分,以管理大型 Web 应用程序的复杂性。

每个部分(“区域”)通常代表大型网站的一个单独部分,用于对相关的控制器和视图集进行分组。

例如

[xhtml]
领域
行政
控制器
楷模
意见
伊尼亚拉索赔
控制器
楷模
意见
[/xhtml]

3. 支持异步控制器:

ASP.NET MVC2 允许控制器异步处理请求。

这可以通过允许频繁调用阻塞操作(如网络请求)的服务器调用非阻塞对应方来提高性能。

4、Action-Method参数中对DefaultValueAttribute的支持:

System.ComponentModel.DefaultValueAttribute类允许为操作方法的参数参数提供默认值。

例如,假设定义了以下默认路由:

[代码]
{控制器}/{动作}/{id}
[/代码]

还假设定义了以下控制器和操作方法:

[代码]
公共类 ArticleController
{
public ActionResult View(int id, [DefaultValue(1)]int page)
{
}
}
[/代码]

以下任何请求 URL 都将调用前面示例中定义的 View 操作方法。

  • /文章/查看/123
  • /Article/View/123?page=1 (效果和之前的请求一样)
  • /文章/查看/123?page=2
5. 支持使用模型绑定器绑定二进制数据:

Html.Hidden助手有两个新的重载,将二进制值编码为 base-64 编码的字符串:

[代码]
public static string Hidden(this HtmlHelper htmlHelper, string name, Binary value);
public static string Hidden(this HtmlHelper htmlHelper, string name, byte[] value);
[/代码]

6.支持DataAnnotations属性:

当我们绑定到模型以提供输入验证时,使用RangeAttributeRequiredAttributeStringLengthAttributeRegexAttribute验证属性(在System.ComponentModel.DataAnnotations命名空间中定义)。

[代码]
使用 System.ComponentModel.DataAnnotations;
命名空间 MvcTmpHlprs
{
[元数据类型(typeof(ProductMD))]
公共部分类产品
{
公开课 ProductMD
{
公共对象 SellStartDate { 获取; 放; }
[UIHint("rbDate")]
公共对象 SellEndDate { 获取; 放; }
[数据类型(数据类型。日期)]
公共对象 DiscontinuedDate { 获取; 放; }
[脚手架柱(假)]
公共对象 ModifiedDate { 获取; 放; }
[脚手架柱(假)]
公共对象 rowguid { 获取; 放; }
[脚手架柱(假)]
公共对象 ThumbnailPhotoFileName { 获取; 放; }
}
}
}
[/代码]

7. 模型验证器提供者:

模型验证提供者类表示为模型提供验证逻辑的抽象。

ASP.NET MVC 包括一个基于System.ComponentModel.DataAnnotations命名空间中包含的验证属性的默认提供程序。

8. 客户端验证:

模型验证器提供程序类以 JSON 序列化数据的形式向浏览器公开验证元数据,客户端验证库可以使用这些数据。

ASP.NET MVC 2 包括一个客户端验证库和适配器,它支持前面提到的DataAnnotations命名空间验证属性。

9. 新的RequireHttpsAttribute动作过滤器:

ASP.NET MVC 2 包括一个新的RequireHttpsAttribute类,可应用于操作方法和控制器。

默认情况下,过滤器将非 SSL (HTTP) 请求重定向到启用 SSL (HTTPS) 的等效请求。

10. 覆盖 HTTP 方法动词:

当我们使用 REST 架构风格构建网站时,HTTP 动词用于确定对资源执行的操作。

REST 要求应用程序支持所有常见的 HTTP 动词,包括GETPUTPOSTDELETE

ASP.NET MVC 2 包括我们可以应用于操作方法的新属性,并且具有紧凑的语法。

这些属性使 ASP.NET MVC 能够根据 HTTP 谓词选择操作方法。

例如, POST请求将调用第一个操作方法,而PUT请求将调用第二个操作方法。

[代码]
[HttpPost]
公共 ActionResult 编辑(int id)

[HttpPut]
public ActionResult Edit(int id, Tag 标签)
[/代码]

在早期版本的 ASP.NET MVC 中,这些操作方法需要更详细的语法,如以下示例所示:

[代码]
[AcceptVerbs(HttpVerbs.Post)]
公共 ActionResult 编辑(int id)

[AcceptVerbs(HttpVerbs.Put)]
public ActionResult Edit(int id, Tag 标签)
[/代码]

由于浏览器仅支持GETPOST HTTP 动词,因此无法发布到需要不同动词的操作。 因此,不可能原生支持所有RESTful请求。

但是,为了在POST操作期间支持RESTful请求,ASP.NET MVC 2 引入了一个新的HttpMethodOverride HTML 帮助器方法。

此方法呈现一个隐藏的输入元素,使表单有效地模拟任何 HTTP 方法。

例如,通过使用HttpMethodOverride HTML 辅助方法,我们可以让表单提交显示为PUTDELETE请求。

HttpMethodOverride的行为影响以下属性:

  • HttpPostAttribute
  • HttpPutAttribute
  • HttpGetAttribute
  • HttpDeleteAttribute
  • AcceptVerbsAttribute
11. 模板化助手的新HiddenInputAttribute类:

我们可以将新的HiddenInputAttribute属性应用于模型属性,以指示在编辑器模板中显示模型时是否应呈现隐藏的输入元素(该属性设置HiddenInput的隐式UIHint值)。

属性的DisplayValue属性允许我们指定值是否在编辑器和显示模式中显示。

DisplayValue设置为 false 时,不会显示任何内容,甚至通常围绕字段的 HTML 标记也不显示。

DisplayValue的默认值为 true。

我们可能会在以下场景中使用HiddenInputAttribute属性:

  • 当视图允许用户编辑对象的 ID 并且需要显示该值以及提供包含旧 ID 的隐藏输入元素以便可以将其传递回控制器时。
  • 当视图允许用户编辑不应显示的二进制属性时,例如时间戳属性。

在这种情况下,不会显示值和周围的 HTML 标记(例如标签和值)。

例如:

[代码]
公共类 ProductViewModel
{
[HiddenInput] // 相当于 [HiddenInput(DisplayValue=true)]
公共 int ID { 获取; 放; }

公共字符串名称 { 获取; 放; }

[隐藏输入(显示值=假)]
公共字节[]时间戳{获取; 放; }
}
[/代码]

12. Html.ValidationSummary Helper 方法可以显示模型级错误:

Html.ValidationSummary辅助方法不是总是显示所有验证错误,而是有一个新选项来仅显示模型级错误。

这使得模型级错误可以显示在验证摘要中,并且特定于字段的错误可以显示在每个字段旁边。

13. Visual Studio 中的 T4 模板生成特定于 .NET Framework 目标版本的代码:

来自 ASP.NET MVC T4 主机的 T4 文件可以使用一个新属性,该属性指定应用程序使用的 .NET Framework 的版本。

这使 T4 模板能够生成特定于 .NET Framework 版本的代码和标记。

在 Visual Studio 2008 中,该值始终为 .NET 3.5。 在 Visual Studio 2010 中,该值为 .NET 3.5 或 .NET4。

14. API 改进:

在 Controller 类中添加了受保护的虚拟CreateActionInvoker方法。

此方法由 Controller 的ActionInvoker属性调用,如果尚未设置调用程序,则允许对调用程序进行延迟实例化。