ASP.NET MVC - 快速指南


ASP.NET MVC - 概述

ASP.NET MVC基本上是微软的一个Web开发框架,它结合了MVC(模型-视图-控制器)架构的特点、敏捷开发的最新思想和技术以及现有ASP的最佳部分.NET 平台。

ASP.NET MVC 并不是从零开始构建的。它是传统 ASP.NET Web 窗体的完全替代方案。它构建在 ASP.NET 之上,因此开发人员在构建 MVC 应用程序时可以享受几乎所有 ASP.NET 功能。

构建 MVC 应用程序

历史

ASP.NET 1.0 于 2002 年 1 月 5 日发布,作为 .Net Framework 1.0 版的一部分。当时,人们很容易将 ASP.NET 和 Web 窗体视为同一事物。然而,ASP.NET 始终支持两层抽象 -

  • System.Web.UI - Web 表单层,包括服务器控件、ViewState 等。

  • System.Web - 它提供基本的 Web 堆栈,包括模块、处理程序、HTTP 堆栈等。

到 2007 年 ASP.NET MVC 发布时,MVC 模式已成为构建 Web 框架最流行的方法之一。

2009 年 4 月,ASP.NET MVC 源代码在 Microsoft 公共许可证 (MS-PL) 下发布。“ASP.NET MVC 框架是一个轻量级、高度可测试的表示框架,与现有的 ASP.NET 功能集成。

其中一些集成功能包括母版页和基于成员资格的身份验证。MVC 框架是在 System.Web.Mvc 程序集中定义的。

2012 年 3 月,微软在开源许可证(Apache License 2.0)下发布了部分 Web 堆栈(包括 ASP.NET MVC、Razor 和 Web API)。ASP.NET Web 窗体未包含在该计划中。

为什么选择 ASP.NET MVC?

Microsoft 决定创建自己的 MVC 框架来构建 Web 应用程序。MVC 框架简单地构建在 ASP.NET 之上。当您使用 ASP.NET MVC 构建 Web 应用程序时,不会有状态错觉,不会出现页面加载和根本没有页面生命周期等情况。

ASP.NET MVC 的另一个设计目标是可以在框架的各个方面进行扩展。因此,当我们谈论视图时,视图必须由特定类型的视图引擎呈现。默认的视图引擎仍然可以接受 ASPX 文件。但如果您不喜欢使用 ASPX 文件,您可以使用其他文件并插入您自己的视图引擎。

MVC 框架内有一个组件可以实例化您的控制器。您可能不喜欢 MVC 框架实例化控制器的方式,您可能想自己处理该工作。因此,MVC 中有很多地方可以注入您自己的自定义逻辑来处理任务。

使用模型视图控制器设计模式背后的整个想法是保持关注点分离。您的控制器不再受制于与 ASP.NET 运行时或与 ASPX 页面的大量联系,这些联系非常难以测试。现在,您只有一个带有常规方法的类,您可以在单元测试中调用该方法来查明该控制器是否会正常运行。

ASP.NET MVC 的优点

以下是使用 ASP.NET MVC 的好处 -

  • 通过将应用程序划分为模型、视图和控制器,可以更轻松地管理复杂性。

  • 实现对渲染的 HTML 的完全控制,并提供清晰的关注点分离。

  • 对 HTML 的直接控制还意味着更好的可访问性,以实现与不断发展的 Web 标准的合规性。

  • 有助于为现有应用程序添加更多交互性和响应能力。

  • 为测试驱动开发(TDD)提供更好的支持。

  • 非常适合由大型开发团队支持的 Web 应用程序以及需要对应用程序Behave进行高度控制的 Web 设计人员。

ASP.NET MVC - 模式

MVC(模型-视图-控制器)设计模式实际上已经存在了几十年,并且已在许多不同的技术中使用。从 Smalltalk 到 C++ 再到 Java,现在的 C Sharp 和 .NET 都使用这种设计模式来构建用户界面。

以下是 MVC 模式的一些显着特征 -

  • 1979 年最初被命名为 Thing-Model-View-Editor,后来简化为 Model-View-Controller。

  • 它是一种强大而优雅的分离应用程序中关注点的方法(例如,将数据访问逻辑与显示逻辑分离),并且非常适合 Web 应用程序。

  • 其明确的关注点分离确实给应用程序的设计增加了少量额外的复杂性,但非凡的好处超过了额外的努力。

MVC 架构模式将应用程序的用户界面 (UI) 分为三个主要部分。

MVC架构模式
  • 模型- 一组描述您正在使用的数据以及业务逻辑的类。

  • 视图- 定义应用程序的 UI 将如何显示。它是纯 HTML,决定了 UI 的外观。

  • 控制器- 一组处理用户通信、整体应用程序流程和特定于应用程序的逻辑的类。

MVC 背后的理念

这个想法是,您将有一个称为视图的组件,它单独负责呈现此用户界面,无论它是 HTML 还是实际上是桌面应用程序上的 UI 小部件。

视图与模型对话,该模型包含视图需要显示的所有数据。视图内部通常没有太多逻辑。

在 Web 应用程序中,视图可能根本没有任何与其关联的代码。它可能只有 HTML,然后是一些表达式,说明从模型中获取数据的位置并将它们插入到您在视图中构建的 HTML 模板内的正确位置。

组织的控制器就是一切。当 MVC 应用程序收到 HTTP 请求时,该请求将被路由到控制器,然后由控制器与数据库、文件系统或模型进行通信。

ASP.NET MVC - 环境设置

MVC 开发工具包含在 Visual Studio 2012 及更高版本中。它还可以安装在 Visual Studio 2010 SP1/Visual Web Developer 2010 Express SP1 上。如果您使用的是 Visual Studio 2010,则可以使用 Web Platform Installer http://www.microsoft.com安装 MVC 4

Microsoft 提供了 Visual Studio 的免费版本,其中还包含 SQL Server,可以从https://www.visualstudio.com下载

安装

步骤 1 - 下载完成后,运行安装程序。将显示以下对话框。

运行安装程序

步骤 2 - 单击“安装”按钮,它将开始安装过程。

安装过程

安装过程成功完成后,您将看到以下对话框。

安装过程完成

步骤 3 - 关闭此对话框并重新启动计算机(如果需要)。

步骤 4 - 从“开始”菜单打开 Visual Studio,这将打开以下对话框。第一次只是为了准备,需要一段时间。

打开视觉工作室

完成所有操作后,您将看到 Visual Studio 的主窗口,如以下屏幕截图所示。

Visual Studio 主窗口

您现在可以开始申请了。

ASP.NET MVC - 入门

在本章中,我们将看一个 ASP.NET MVC 的简单工作示例。我们将在这里构建一个简单的网络应用程序。为了创建 ASP.NET MVC 应用程序,我们将使用 Visual Studio 2015,它包含创建、测试和部署 MVC 框架应用程序所需的所有功能。

创建 ASP.Net MVC 应用程序

以下是使用 Visual Studio 中提供的项目模板创建项目的步骤。

步骤 1 - 打开 Visual Studio。单击文件 → 新建 → 项目菜单选项。

将打开一个新的项目对话框。

项目菜单选项

步骤 2 - 从左侧窗格中,选择模板 → Visual C# → Web。

步骤 3 - 在中间窗格中,选择 ASP.NET Web 应用程序。

步骤 4 - 在“名称”字段中输入项目名称 MVCFirstApp,然后单击“确定”继续。您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。

输入项目名称

步骤 5 - 为了简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框。单击“确定”。

它将创建一个具有最少预定义内容的基本 MVC 项目。

Visual Studio 创建项目后,您将看到“解决方案资源管理器”窗口中显示许多文件和文件夹。

创建 ASP.Net MVC 项目

如您所知,我们已经从空项目模板创建了 ASP.Net MVC 项目,因此目前应用程序不包含任何要运行的内容。

步骤 6 - 从“调试”→“开始调试”菜单选项运行此应用程序,您将看到404 未找到错误。

404 未找到错误

默认浏览器是 Internet Explorer,但您可以从工具栏中选择已安装的任何浏览器。

添加控制器

要消除 404 Not Found 错误,我们需要添加一个控制器来处理所有传入请求。

步骤 1 - 要添加控制器,请右键单击解决方案资源管理器中的控制器文件夹,然后选择添加 → 控制器。

添加控制器

它将显示“添加支架”对话框。

控制器支架对话框

步骤 2 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

添加控制器对话框

步骤 3 - 将名称设置为 HomeController 并单击“添加”按钮。

您将在 Controllers 文件夹中看到一个新的 C# 文件 HomeController.cs,该文件也可以在 Visual Studio 中打开以进行编辑。

C# 家庭控制器

步骤 4 - 为了使其成为一个可行的示例,让我们通过使用以下代码更改名为Index 的操作方法来修改控制器类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCFirstApp.Controllers {
   public class HomeController : Controller {
      // GET: Home
      public string Index(){
         return "Hello World, this is ASP.Net MVC Tutorials";
      }
   }
}

步骤 5 - 运行此应用程序,您将看到浏览器正在显示 Index 操作方法的结果。

指数行动方法

ASP.NET MVC - 生命周期

在本章中,我们将讨论整个 MVC 管道以及 HTTP 请求在 ASP.NET 中的 MVC 框架中传输时的生命周期。从高层次来看,生命周期只是用于处理某种类型的请求或更改应用程序状态的一系列步骤或事件。您可能已经熟悉各种框架生命周期,这个概念并不是 MVC 所独有的。

例如,ASP.NET Webforms 平台具有复杂的页面生命周期。其他 .NET 平台(例如 Windows 手机应用程序)有自己的应用程序生命周期。无论技术如何,对于所有这些平台来说,了解处理管道可以帮助您更好地利用可用功能,MVC 也不例外。

MVC 有两个生命周期 -

  • 应用程序生命周期
  • 请求生命周期
MVC 生命周期

应用程序生命周期

应用程序生命周期是指应用程序进程实际开始运行 IIS 直到停止的时间。这是由应用程序启动文件中的应用程序启动和结束事件标记的。

请求生命周期

这是我们的应用程序每次处理 HTTP 请求时发生的事件序列。

每个 MVC 应用程序的入口点都从路由开始。ASP.NET 平台收到请求后,它会通过 URL 路由模块确定如何处理该请求。

模块是可以连接到应用程序生命周期并添加功能的 .NET 组件。路由模块负责将传入的 URL 与我们在应用程序中定义的路由进行匹配。

所有路由都有一个关联的路由处理程序,这是 MVC 框架的入口点。

路由处理程序

MVC 框架负责将路由数据转换为可以处理请求的具体控制器。创建控制器后,下一个主要步骤是Action Execution称为操作调用程序的组件会查找并选择适当的操作方法来调用控制器。

准备好操作结果后,就会触发下一个阶段,即结果执行。MVC 将声明结果与执行结果分开。如果结果是视图类型,则将调用视图引擎,它负责查找和渲染我们的视图。

如果结果不是视图,则操作结果将自行执行。此结果执行会生成对原始 HTTP 请求的实际响应。

ASP.NET MVC - 路由

路由是将 HTTP 请求定向到控制器的过程,此处理的功能在 System.Web.Routing 中实现。此程序集不是 ASP.NET MVC 的一部分。它实际上是 ASP.NET 运行时的一部分,并作为 .NET 3.5 SP1 与 ASP.NET 一起正式发布。

System.Web.Routing由 MVC 框架使用,但也由 ASP.NET 动态数据使用。MVC 框架利用路由将请求定向到控制器。Global.asax 文件是应用程序的一部分,您将在其中定义应用程序的路由。

这是来自我们在上一章中创建的 MVC 应用程序的 Global.asax 中的应用程序启动事件的代码。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCFirstApp {
   public class MvcApplication : System.Web.HttpApplication {
      protected void Application_Start(){
         AreaRegistration.RegisterAllAreas();
         RouteConfig.RegisterRoutes(RouteTable.Routes);
      }
   }
}

以下是 RouteConfig 类的实现,其中包含一个方法 RegisterRoutes。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCFirstApp {
   public class RouteConfig {
      public static void RegisterRoutes(RouteCollection routes){
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
         routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new{ controller = "Home", action = "Index", id = UrlParameter.Optional});
      }
   }
}

您将定义路由,这些路由会将 URL 映射到特定的控制器操作。动作只是控制器上的一个方法。它还可以从该 URL 中选取参数并将它们作为参数传递到方法中。

所以应用程序中定义的这条路由就是默认路由。如上面的代码所示,当您看到 URL 以 (something)/(something)/(something) 的形式到达时,那么第一部分是控制器名称,第二部分是操作名称,第三部分是一个 ID 参数。

了解路线

MVC 应用程序使用 ASP.NET 路由系统,该系统决定 URL 如何映射到控制器和操作。

当 Visual Studio 创建 MVC 项目时,它会添加一些默认路由来帮助我们开始。当您运行应用程序时,您将看到 Visual Studio 已将浏览器定向到端口 63664。您几乎肯定会在浏览器请求的 URL 中看到不同的端口号,因为 Visual Studio 在创建项目时分配了一个随机端口。

本地主机主页

在上一个示例中,我们添加了一个 HomeController,因此您还可以请求以下任何 URL,它们将被定向到 HomeController 上的 Index 操作。

http://localhost:63664/首页/

http://localhost:63664/Home/索引

当浏览器请求 http://mysite/ 或 http://mysite/Home 时,它​​会从 HomeController 的 Index 方法获取输出。

您也可以通过更改浏览器中的 URL 来尝试此操作。在此示例中,它是 http://localhost:63664/,但端口可能不同。

如果将 /Home 或 /Home/Index 附加到 URL 并按“Enter”按钮,您将从 MVC 应用程序中看到相同的结果。

本地主机主页索引

正如您在本例中所看到的,约定是我们有一个名为 HomeController 的控制器,并且该 HomeController 将成为我们的 MVC 应用程序的起点。

Visual Studio 为新项目创建的默认路由假定您将遵循此约定。但如果您想遵循自己的约定,那么您需要修改路线。

海关惯例

您当然可以添加自己的路线。如果您不喜欢这些操作名称,如果您有不同的 ID 参数,或者您的网站通常有不同的 URL 结构,那么您可以添加自己的路由条目。

让我们看一个简单的例子。假设我们有一个包含进程列表的页面。以下是代码,它将路由到流程页面。

routes.MapRoute(
   "Process",
   "Process/{action}/{id}",
   defaults: new{
      controller = "Process", action = "List ", id = UrlParameter.Optional}
);

当有人进来并寻找带有 Process/Action/Id 的 URL 时,他们将转到 Process Controller。我们可以使操作有点不同,默认操作,我们可以将其设置为列表而不是索引。

现在到达的请求看起来像 localhosts/process。路由引擎将使用此路由配置来传递它,因此它将使用默认操作 List。

以下是完整的类实现。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCFirstApp{
   public class RouteConfig{
      public static void RegisterRoutes(RouteCollection routes){
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
			
         routes.MapRoute(
            "Process", "Process/{action}/{id}",
            defaults: new{
               controller = " Process", action = "List ", id =
               UrlParameter.Optional});
					
         routes.MapRoute(
            name: "Default", url: "{controller}/{action}/{id}",
            defaults: new{
               controller = "Home", action = "Index", id =
               UrlParameter.Optional});
      }
   }
}

步骤 1 - 运行此命令并使用以下 URL http://localhost:63664/Process请求流程页面

本地主机进程

您将看到 HTTP 404,因为路由引擎正在寻找不可用的 ProcessController。

步骤 2 - 通过右键单击解决方案资源管理器中的 Controllers 文件夹并选择添加 → 控制器来创建 ProcessController。

创建进程控制器

它将显示“添加支架”对话框。

ProcessController 脚手架对话框

步骤 3 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

空选项添加按钮

步骤 4 - 将名称设置为 ProcessController 并单击“添加”按钮。

现在,您将在 Controllers 文件夹中看到一个新的 C# 文件 ProcessController.cs,该文件也可以在 Visual Studio 中打开以进行编辑。

设置进程控制器

现在我们的默认操作将是列表,因此我们希望这里有一个列表操作而不是索引。

步骤 5 - 将返回类型从 ActionResult 更改为字符串,并使用以下代码从此操作方法返回一些字符串。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFirstApp.Controllers{
   public class ProcessController : Controller{
      // GET: Process
      public string List(){
         return "This is Process page";
      }
   }
}

步骤 6 - 当您运行此应用程序时,您将再次看到默认路由的结果。当您指定以下 URL http://localhost:63664/Process/List 时,您将看到来自 ProcessController 的结果。

本地主机进程列表

ASP.NET MVC - 控制器

控制器本质上是 ASP.NET MVC 应用程序的中央单元。它是第一个接收者,与传入的 HTTP 请求交互。因此,控制器决定选择哪个模型,然后从模型中获取数据,并在渲染视图后将其传递到相应的视图。实际上,控制器正在控制应用程序获取输入并呈现正确输出的整体流程。

控制器是继承自 System.Web.Mvc.Controller 的 C# 类,System.Web.Mvc.Controller 是内置控制器基类。控制器中的每个公共方法都称为操作方法,这意味着您可以通过某个 URL 从 Web 调用它来执行操作。

MVC 约定是将控制器放在 Visual Studio 在设置项目时创建的 Controllers 文件夹中。

让我们通过创建一个新的 ASP.Net MVC 项目来看一个简单的 Controller 示例。

步骤 1 - 打开 Visual Studio 并单击“文件”→“新建”→“项目”菜单选项。

将打开一个新的项目对话框。

Visual Studio 项目菜单

步骤 2 - 从左侧窗格中,选择模板 → Visual C# → Web。

步骤 3 - 在中间窗格中,选择 ASP.NET Web 应用程序。

步骤 4 - 在“名称”字段中输入项目名称“MVCControllerDemo”,然后单击“确定”继续。您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。

MVC控制器演示

步骤 5 - 为了简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框,然后单击“确定”。

它将创建一个具有最少预定义内容的基本 MVC 项目。

Visual Studio 创建项目后,您将看到“解决方案资源管理器”窗口中显示许多文件和文件夹。

由于我们是从空项目模板创建 ASP.Net MVC 项目,因此目前该应用程序不包含任何要运行的内容。

步骤 6 - 通过右键单击解决方案资源管理器中的 Controllers 文件夹来添加 EmployeeController。选择添加 → 控制器。

员工控制器

它将显示“添加支架”对话框。

EmployeeController 脚手架对话框

步骤 7 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

MVC 5 控制器

步骤 8 - 将名称设置为 EmployeeController 并单击“添加”按钮。

您将在 Controllers 文件夹中看到一个新的 C# 文件 EmployeeController.cs,该文件也可以在 Visual Studio 中打开以供编辑。

自定义路由员工控制器

现在,在此应用程序中,我们将为具有默认路由的 Employee 控制器添加自定义路由。

步骤 1 - 转到“App_Start”文件夹下的“RouteConfig.cs”文件并添加以下路由。

routes.MapRoute(
   "Employee", "Employee/{name}", new{
      controller = "Employee", action = "Search", name =
      UrlParameter.Optional });

以下是 RouteConfig.cs 文件的完整实现。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCControllerDemo {
   public class RouteConfig {
      public static void RegisterRoutes(RouteCollection routes){
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
			
         routes.MapRoute(
            "Employee", "Employee/{name}", new{
               controller = "Employee", action = "Search", name = UrlParameter.Optional });
					
         routes.MapRoute(
            name: "Default", url: "{controller}/{action}/{id}", defaults: new{
               controller = "Home", action = "Index", id = UrlParameter.Optional });
      }
   }
}

考虑一个场景,其中任何用户来搜索员工,并指定 URL“Employee/Mark”。在这种情况下,Mark 将被视为参数名称,而不是像 Action 方法那样。因此,在这种情况下,我们的默认路由将不起作用。

为了在传递参数时从浏览器获取传入值,MVC 框架提供了一种简单的方法来解决这个问题。这是通过使用 Action 方法内的参数来实现的。

步骤 2 - 使用以下代码更改 EmployeeController 类。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers  {
   public class EmployeeController : Controller {
      // GET: Employee
      public ActionResult Search(string name){
         var input = Server.HtmlEncode(name);
         return Content(input);
      }
   }
}

如果您向操作方法添加参数,那么 MVC 框架将查找与参数名称匹配的值。它将应用所有可能的组合来找出参数值。它将搜索路线数据、查询字符串等。

因此,如果您请求“/Employee/Mark”,那么 MVC 框架将决定我需要一个带有“UserInput”的参数,然后将从 URL 中选取 Mark 并自动传递。

Server.HtmlEncode 将简单地将任何类型的恶意脚本转换为纯文本。当上面的代码被编译并执行并请求以下 URL http://localhost:61465/Employee/Mark 时,您将得到以下输出。

本地主机员工马克

正如您在上面的屏幕截图中看到的,Mark 是从 URL 中选取的。

ASP.NET MVC - 操作

ASP.NET MVC 操作方法负责执行请求并生成对其的响应。默认情况下,它会生成 ActionResult 形式的响应。操作通常与用户交互具有一对一的映射。

例如,在浏览器中输入 URL、单击任何特定链接并提交表单等。这些用户交互中的每一个都会导致将请求发送到服务器。在每种情况下,请求的 URL 都包含 MVC 框架用于调用操作方法的信息。对操作方法的一个限制是它们必须是实例方法,因此它们不能是静态方法。而且没有返回值限制。所以你可以返回字符串、整数等。

请求处理

操作是 MVC 应用程序中的最终请求目的地,它使用控制器基类。让我们看一下请求处理。

  • 当 URL 到达时,例如 /Home/index,UrlRoutingModule 会检查并了解路由表中配置的内容是否知道如何处理该 URL。

请求处理
  • UrlRoutingModule 将我们在路由表中配置的信息放在一起,并将控制权移交给 MVC 路由处理程序。

  • MVC 路由处理程序将控制器传递给 MvcHandler,它是一个 HTTP 处理程序。

  • MvcHandler 使用控制器工厂来实例化控制器,并且它知道要实例化哪个控制器,因为它在 RouteData 中查找该控制器值。

  • 一旦MvcHandler有了控制器,MvcHandler唯一知道的就是IController接口,所以它只是告诉控制器执行。

  • 当它告诉控制器执行时,它是从 MVC 的控制器基类派生的。Execute 方法创建一个操作调用程序,并告诉该操作调用程序去查找要调用的方法,找到要调用的操作。

  • 操作调用程序再次查看 RouteData 并找到从路由引擎传递的操作参数。

行动类型

操作基本上返回不同类型的操作结果。ActionResult 类是所有操作结果的基础。以下是不同类型的操作结果及其Behave的列表。

先生。 姓名和Behave
1

内容结果

返回一个字符串

2

文件内容结果

返回文件内容

3

文件路径结果

返回文件内容

4

文件流结果

返回文件内容

5

空结果

不返回任何内容

6

JavaScript结果

返回执行脚本

7

Json结果

返回 JSON 格式的数据

8

重定向到结果

重定向到指定的 URL

9

Http未授权结果

返回 403 HTTP 状态代码

10

重定向到路由结果

重定向到不同的操作/不同的控制器操作

11

查看结果

作为视图引擎的响应收到

12

部分查看结果

作为视图引擎的响应收到

让我们看一下上一章中的一个简单示例,其中我们创建了一个 EmployeeController。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers {
   public class EmployeeController : Controller{
      // GET: Employee
      public ActionResult Search(string name){
         var input = Server.HtmlEncode(name);
         return Content(input);
      }
   }
}

当您请求以下 URL http://localhost:61465/Employee/Mark时,您将收到以下输出作为操作。

本地主机员工标记输出

添加控制器

让我们添加另一个控制器。

步骤 1 - 右键单击​​控制器文件夹并选择添加 → 控制器。

添加另一个控制器

它将显示“添加支架”对话框。

添加脚手架对话框

步骤 2 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

客户控制器

步骤 3 - 将名称设置为 CustomerController 并单击“添加”按钮。

现在,您将在 Controllers 文件夹中看到一个新的 C# 文件“CustomerController.cs”,该文件也可以在 Visual Studio 中打开以进行编辑。

set_name 客户控制器

同样,再添加一个名为 HomeController 的控制器。以下是 HomeController.cs 类的实现。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public string Index(){
         return "This is Home Controller";
      }
   }
}

步骤 4 - 运行此应用程序,您将收到以下输出。

家庭控制器输出

步骤 5 - 在我们上面创建的客户控制器中添加以下代码。

public string GetAllCustomers(){
   return @"<ul>
      <li>Ali Raza</li>
      <li>Mark Upston</li>
      <li>Allan Bommer</li>
      <li>Greg Jerry</li>
   </ul>";
}

步骤 6 - 运行此应用程序并请求http://localhost:61465/Customer/GetAllCustomers。您将看到以下输出。

本地主机获取所有客户

您还可以重定向到同一控制器甚至不同控制器的操作。

以下是一个简单的示例,我们将通过使用以下代码更改 HomeController 中的代码来从 HomeController 重定向到 Customer Controller。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers{
   public class HomeController : Controller{
      // GET: Home
      public ActionResult Index(){
         return RedirectToAction("GetAllCustomers","Customer");
      }
   }
}

正如您所看到的,我们使用了 RedirectToAction() 方法 ActionResult,它采用两个参数:操作名称和控制器名称。

当您运行此应用程序时,您将看到默认路由将其重定向到 /Customer/GetAllCustomers

本地主机客户 GetAllCustomers

ASP.NET MVC - 过滤器

在 ASP.NET MVC 中,控制器定义的操作方法通常与可能的用户交互具有一对一的关系,但有时您希望在调用操作方法之前或操作方法运行之后执行逻辑。

为了支持这一点,ASP.NET MVC 提供了过滤器。过滤器是自定义类,它提供声明性和编程方式来向控制器操作方法添加操作前和操作后Behave。

动作过滤器

操作过滤器是一个属性,您可以将其应用于控制器操作或整个控制器,以修改操作的执行方式。ASP.NET MVC 框架包括几个动作过滤器 -

  • OutputCache - 将控制器操作的输出缓存指定的时间。

  • HandleError - 处理执行控制器操作时引发的错误。

  • 授权- 使您能够限制对特定用户或角色的访问。

过滤器的类型

ASP.NET MVC 框架支持四种不同类型的过滤器 -

  • 授权过滤器- 实现 IAuthorizationFilter 属性。

  • 动作过滤器- 实现 IActionFilter 属性。

  • 结果过滤器- 实现 IResultFilter 属性。

  • 异常过滤器- 实现 IExceptionFilter 属性。

过滤器按照上面列出的顺序执行。例如,授权过滤器始终在操作过滤器之前执行,异常过滤器始终在所有其他类型的过滤器之后执行。

授权过滤器用于实现控制器操作的身份验证和授权。例如,授权过滤器是授权过滤器的一个示例。

让我们看一个创建新的 ASP.Net MVC 项目的简单示例。

步骤 1 - 打开 Visual Studio 并单击文件 → 新建 → 项目菜单选项。

将打开一个新的项目对话框。

新项目菜单选项

步骤 2 - 从左侧窗格中,选择模板 → Visual C# → Web。

步骤 3 - 在中间窗格中,选择 ASP.NET Web 应用程序。

步骤 4 - 在“名称”字段中输入项目名称 MVCFiltersDemo,然后单击“确定”继续,您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。

MVC过滤器演示

步骤 5 - 为了简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框,然后单击“确定”。

它将创建一个具有最少预定义内容的基本 MVC 项目。

步骤 6 - 要添加控制器,请右键单击解决方案资源管理器中的控制器文件夹,然后选择添加 → 控制器。

它将显示“添加支架”对话框。

控制器添加脚手架对话框

步骤 7 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

添加控制器对话框

步骤 8 - 将名称设置为 HomeController 并单击“添加”按钮。

您将在 Controllers 文件夹中看到一个新的 C# 文件“HomeController.cs”,该文件也可以在 Visual Studio 中打开以进行编辑。

应用操作过滤器

动作过滤器可以应用于单个控制器动作或整个控制器。例如,操作过滤器OutputCache应用于返回字符串的名为 Index() 的操作。此过滤器会导致操作返回的值被缓存 15 秒。

为了使其成为一个可行的示例,让我们通过使用以下代码更改名为Index 的操作方法来修改控制器类。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      [OutputCache(Duration = 15)]
		
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      }
   }
}

当您运行此应用程序时,您将看到浏览器正在显示 Index 操作方法的结果。

MVC 过滤器教程

让我们添加另一个操作方法,它将显示当前时间。

namespace MVCFiltersDemo.Controllers{
   public class HomeController : Controller{
      // GET: Home
		
      [OutputCache(Duration = 15)]
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      }
		
      [OutputCache(Duration = 20)]
      public string GetCurrentTime(){
         return DateTime.Now.ToString("T");
      }
   }
}

请求以下 URL http://localhost:62833/Home/GetCurrentTime,您将收到以下输出。

本地主机获取当前时间

如果刷新浏览器,您将看到相同的时间,因为该操作已缓存 20 秒。20秒后刷新就会更新。

自定义过滤器

为了创建您自己的自定义过滤器,ASP.NET MVC 框架提供了一个称为 ActionFilterAttribute 的基类。该类实现了 IActionFilter 和 IResultFilter 接口,并且两者均派生自 Filter 类。

让我们看一下自定义过滤器的简单示例,方法是使用 ActionFilters 在项目中创建一个新文件夹。添加一个类,右键单击 ActionFilters 文件夹并选择“添加”→“类”。

自定义过滤器

在名称字段中输入“MyLogActionFilter”,然后单击“添加”按钮。

此类将从 ActionFilterAttribute 派生它是基类并重写以下方法。以下是 MyLogActionFilter 的完整实现。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCFiltersDemo.ActionFilters {
   public class MyLogActionFilter : ActionFilterAttribute{
      public override void OnActionExecuting(ActionExecutingContext filterContext){
         Log("OnActionExecuting", filterContext.RouteData);
      }
		
      public override void OnActionExecuted(ActionExecutedContext filterContext){
         Log("OnActionExecuted", filterContext.RouteData);
      }
		
      public override void OnResultExecuting(ResultExecutingContext filterContext){
         Log("OnResultExecuting", filterContext.RouteData);
      }
		
      public override void OnResultExecuted(ResultExecutedContext filterContext){
         Log("OnResultExecuted", filterContext.RouteData);
      }
		
      private void Log(string methodName, RouteData routeData){
         var controllerName = routeData.Values["controller"];
         var actionName = routeData.Values["action"];
			
         var message = String.Format(
            "{0} controller:{1} action:{2}", methodName, controllerName, actionName);
				
         Debug.WriteLine(message, "Action Filter Log");
      }
   }
}

现在让我们使用以下代码将日志过滤器应用到 HomeController。

using MVCFiltersDemo.ActionFilters;
using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers {
   [MyLogActionFilter]
   public class HomeController : Controller{
      // GET: Home
		
      [OutputCache(Duration = 10)]
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      }
		
      [OutputCache(Duration = 10)]
      public string GetCurrentTime(){
         return DateTime.Now.ToString("T");
      }
   }
}

运行应用程序,然后观察输出窗口。

输出窗口

如上面的屏幕截图所示,处理操作的阶段会记录到 Visual Studio 输出窗口中。

ASP.NET MVC - 选择器

操作选择器是可应用于操作方法的属性,用于影响调用哪个操作方法来响应请求。它帮助路由引擎选择正确的操作方法来处理特定的请求。

当您编写操作方法时,它起着非常重要的作用。这些选择器将根据操作方法前面给出的修改名称来决定方法调用的Behave。它通常用于操作方法名称的别名。

动作选择器属性分为三种类型 -

  • 动作名称
  • 不采取行动
  • Behave动词

动作名称

此类表示用于操作名称的属性。它还允许开发人员使用与方法名称不同的操作名称。

让我们看一下上一章中的一个简单示例,其中 HomeController 包含两个操作方法。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      } 
		
      public string GetCurrentTime(){
         return DateTime.Now.ToString("T");
      }
   }
}

让我们通过在 GetCurrentTime() 上方写入 [ActionName("CurrentTime")] 来应用 GetCurrentTime 的 ActionName 选择器,如以下代码所示。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      }
		
      [ActionName("CurrentTime")]
      public string GetCurrentTime(){
         return DateTime.Now.ToString("T");
      }
   }
}

现在运行此应用程序并在浏览器中输入以下 URL http://localhost:62833/Home/CurrentTime,您将收到以下输出。

本地主机当前时间

你可以看到我们使用了CurrentTime来代替原来的action名称,即上面URL中的GetCurrentTime。

不采取行动

NonAction 是另一个内置属性,它指示 Controller 的公共方法不是操作方法。当您希望某个方法不应该被视为操作方法时,可以使用它。

让我们看一个简单的示例,在 HomeController 中添加另一个方法,并使用以下代码应用 NonAction 属性。

using MVCFiltersDemo.ActionFilters;
using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCFiltersDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public string Index(){
         return "This is ASP.Net MVC Filters Tutorial";
      }
		
      [ActionName("CurrentTime")]
      public string GetCurrentTime(){
         return TimeString();
      }
		
      [NonAction]
      public string TimeString(){
         return "Time is " + DateTime.Now.ToString("T");
      }
   }
}

新方法 TimeString 是从 GetCurrentTime() 调用的,但您不能将其用作 URL 中的操作。

让我们运行此应用程序并在浏览器中指定以下 URL http://localhost:62833/Home/CurrentTime 。您将收到以下输出。

本地主机主页当前时间

现在让我们检查URL 中的/TimeString作为操作,看看会发生什么。

时间串

您可以看到它给出了“404—Not Found”错误。

Behave动词

您可以应用的另一个选择器过滤器是 ActionVerbs 属性。因此,这限制了对特定 HttpVerbs 的特定操作的指示。您可以定义两个具有相同名称的不同操作方法,但一个操作方法响应 HTTP Get 请求,另一个操作方法响应 HTTP Post 请求。

MVC 框架支持以下 ActionVerb。

  • HttpGet
  • HttpPost
  • HttpPut
  • Http删除
  • Http选项
  • Http补丁

让我们看一个简单的例子,我们将在其中创建 EmployeeController。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers {
   public class EmployeeController : Controller{
      // GET: Employee
      public ActionResult Search(string name = “No name Entered”){
         var input = Server.HtmlEncode(name);
         return Content(input);
      }
   }
}

现在让我们使用以下代码添加另一个同名的操作方法。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers {
   public class EmployeeController : Controller{
      // GET: Employee
      //public ActionResult Index()
      //{
         // return View();
      //}
		
      public ActionResult Search(string name){
         var input = Server.HtmlEncode(name);
         return Content(input);
      }
		
      public ActionResult Search(){
         var input = "Another Search action";
         return Content(input);
      }
   }
}

当您运行此应用程序时,它将给出错误,因为 MVC 框架无法确定应为请求选择哪个操作方法。

让我们使用以下代码指定 HttpGet ActionVerb 以及您想要作为响应的操作。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCControllerDemo.Controllers {
   public class EmployeeController : Controller{
      // GET: Employee
      //public ActionResult Index()
      //{
         // return View();
      //}
		
      public ActionResult Search(string name){
         var input = Server.HtmlEncode(name);
         return Content(input);
      }
		
      [HttpGet]
      public ActionResult Search(){
         var input = "Another Search action";
         return Content(input);
      }
   }
}

当您运行此应用程序时,您将收到以下输出。

另一个搜索动作

ASP.NET MVC - 视图

在 ASP.NET MVC 应用程序中,没有任何东西类似于页面,并且当您在 URL 中指定路径时,它也不包含与页面直接对应的任何内容。ASP.NET MVC 应用程序中最接近页面的东西称为视图

在 ASP.NET MVC 应用程序中,所有传入的浏览器请求都由控制器处理,并将这些请求映射到控制器操作。控制器操作可能会返回视图,也可能执行某些其他类型的操作,例如重定向到另一个控制器操作。

让我们通过创建一个新的 ASP.NET MVC 项目来看一个简单的 View 示例。

步骤 1 - 打开 Visual Studio 并单击文件 → 新建 → 项目菜单选项。

将打开一个新的项目对话框。

视觉工作室

步骤 2 - 从左侧窗格中,选择模板 → Visual C# → Web。

步骤 3 - 在中间窗格中,选择 ASP.NET Web 应用程序。

步骤 4 - 在“名称”字段中输入项目名称“MVCViewDemo”,然后单击“确定”继续。您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。

MVC视图演示

步骤 5 - 为了简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框,然后单击“确定”。

它将创建一个具有最少预定义内容的基本 MVC 项目。我们现在需要添加控制器。

步骤 6 - 右键单击​​解决方案资源管理器中的控制器文件夹,然后选择添加 → 控制器。

它将显示“添加支架”对话框。

控制器文件夹

步骤 7 - 选择 MVC 5 Controller – Empty 选项,然后单击“添加”按钮。

将出现“添加控制器”对话框。

添加控制器对话框

步骤 8 - 将名称设置为 HomeController 并单击“添加”按钮。

您将在 Controllers 文件夹中看到一个新的 C# 文件“HomeController.cs”,该文件也可以在 Visual Studio 中打开以供编辑。

让我们更新 HomeController.cs 文件,其中包含两个操作方法,如以下代码所示。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCViewDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public ActionResult Index(){
         return View();
      }
		
      public string Mycontroller(){
         return "Hi, I am a controller";
      }
   }
}

步骤 9 - 运行此应用程序并将 /Home/MyController 附加到浏览器中的 URL,然后按 Enter。您将收到以下输出。

我的控制器

由于 MyController 操作仅返回字符串,因此要从操作返回视图,我们需要首先添加视图。

步骤 10 - 在添加视图之前,让我们添加另一个操作,该操作将返回默认视图。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCViewDemo.Controllers {
   public class HomeController : Controller{
      // GET: Home
      public ActionResult Index(){
         return View();
      }
		
      public string Mycontroller(){
         return "Hi, I am a controller";
      }
		
      public ActionResult MyView(){
         return View();
      }
   }
}

步骤 11 - 运行此应用程序并将 /Home/MyView 附加到浏览器中的 URL,然后按 Enter。您将收到以下输出。

我的视图 查看

您可以在这里看到我们有一个错误,这个错误实际上非常具有描述性,它告诉我们它找不到 MyView 视图。

步骤 12 - 要添加视图,请在 MyView 操作内右键单击并选择添加视图。

我的视图操作

它将显示“添加视图”对话框,并且将添加默认名称。

添加视图对话框

步骤 13 - 取消选中“使用布局页面”复选框,然后单击“添加”按钮。

我们现在在视图中拥有默认代码。

使用布局页面

步骤 14 - 使用以下代码在此视图中添加一些文本。

@{
   Layout = null;
}

<!DOCTYPE html>
<html>
   <head>
      <meta name = "viewport" content = "width = device-width" />
      <title>MyView</title>
   </head>
	
   <body>
      <div>
         Hi, I am a view
      </div>
   </body>
	
</html>

步骤 15 - 运行此应用程序并将 /Home/MyView 附加到浏览器中的 URL。按 Enter 键,您将收到以下输出。

我是观

您现在可以从视图中看到文本。

ASP.NET MVC - 数据模型

在本章中,我们将讨论如何在 ASP.NET MVC 框架应用程序中构建模型。模型存储根据来自控制器的命令检索并显示在视图中的数据

模型是类的集合,您将在其中处理数据和业务逻辑。因此,基本上模型是特定于业务领域的容器。它用于与数据库交互。它还可用于操作数据以实现业务逻辑。

让我们通过创建一个新的 ASP.Net MVC 项目来看看 Model 的简单示例。

步骤 1 - 打开 Visual Studio。单击文件 → 新建 → 项目菜单选项。

将打开一个新的项目对话框。

打开视觉工作室

步骤 2 - 从左侧窗格中,选择模板 → Visual C# → Web。

步骤 3 - 在中间窗格中,选择 ASP.NET Web 应用程序。

步骤 4 - 在“名称”字段中输入项目名称“MVCSimpleApp”,然后单击“确定”继续。您将看到以下对话框,要求您设置 ASP.NET 项目的初始内容。

MVC简单应用程序

步骤 5 - 为了简单起见,选择“空”选项并选中“添加文件夹和核心引用”部分中的 MVC 复选框,然后单击“确定”。

它将创建一个具有最少预定义内容的基本 MVC 项目。

我们现在需要添加一个控制器。

步骤 6 - 右键单击​​解决方案资源管理器中的控制器文件夹,然后选择添加 → 控制器。

它将显示“添加支架”对话框。

右键单击控制器文件夹

步骤 7 - 选择 MVC 5 控制器 - 带读/写操作选项。该模板将为控制器创建一个具有默认操作的 Index 方法。这还将列出其他方法,例如编辑/删除/创建。

步骤 8 - 单击“添加”按钮,将出现“添加控制器”对话框。

添加员工控制器

步骤 9 - 将名称设置为 EmployeeController 并单击“添加”按钮。

步骤 10 - 您将在 Controllers 文件夹中看到一个新的 C# 文件“EmployeeController.cs”,该文件已打开,可在 Visual Studio 中使用一些默认操作进行编辑。

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCSimpleApp.Controllers {
   public class EmployeeController : Controller{
      // GET: Employee
      public ActionResult Index(){
         return View();
      }
		
      // GET: Employee/Details/5
      public ActionResult Details(int id){
         return View();
      }
		
      // GET: Employee/Create
      public ActionResult Create(){
         return View();
      }
		
      // POST: Employee/Create
      [HttpPost]
      public ActionResult Create(FormCollection collection){
         try{
            // TODO: Add insert logic here
            return RedirectToAction("Index");
         }catch{
            return View();
         }
      }
		
      // GET: Employee/Edit/5
      public ActionResult Edit(int id){
         return View();
      }
		
      // POST: Employee/Edit/5
      [HttpPost]
      public ActionResult Edit(int id, FormCollection collection){
         try{
            // TODO: Add update logic here
            return RedirectToAction("Index");
         }catch{
            return View();
         }
      }
		
      // GET: Employee/Delete/5
      public ActionResult Delete(int id){
         return View();
      }
		
      // POST: Employee/Delete/5
      [HttpPost]
      public ActionResult Delete(int id, FormCollection collection){
         try{
            // TODO: Add delete logic here
            return RedirectToAction("Index");
         }catch{
            return View();