添加新控制器

作者: 里克·安德森

注释

本教程的更新版本可在 此处 找到,并使用了最新版本的 Visual Studio。 新教程使用 ASP.NET Core MVC,这为本教程提供了 许多 改进。

本教程讲解了使用控制器和视图的 ASP.NET Core MVC。 Razor Pages 是 ASP.NET Core 中的一种新替代方法,它是一种基于页面的编程模型,使生成 Web UI 更加轻松高效。 建议在 MVC 版本之前试用 Razor Pages 教程。 Razor Pages 教程:

  • 更易于遵循。
  • 涵盖更多功能。
  • 是新应用开发的首选方法。

MVC 代表 model-view-controller。 MVC 是开发设计良好、可测试且易于维护的应用程序的模式。 基于 MVC 的应用程序包含:

  • M odels:表示应用程序数据的类,以及使用验证逻辑对这些数据强制执行业务规则的类。
  • V iews:应用程序用于动态生成 HTML 响应的模板文件。
  • C ontrollers:处理传入浏览器请求、检索模型数据的类,然后指定返回对浏览器的响应的视图模板。

我们将介绍本教程系列中的所有概念,并介绍如何使用它们来生成应用程序。

让我们首先创建控制器类。 在 解决方案资源管理器中,右键单击 “控制器 ”文件夹,然后单击“ 添加”,然后单击“ 控制器”。

显示“解决方案资源管理器”窗口的屏幕截图。控制器右键单击菜单和“添加”子菜单处于打开状态。

“添加基架 ”对话框中,单击 “MVC 5 控制器 - 空”,然后单击“ 添加”。

显示“添加基架”对话框的屏幕截图。已选择空的 M V C 5 控制器。

将新控制器命名为“HelloWorldController”,然后单击“ 添加”。

添加控制器

请注意, 解决方案资源管理器 中已创建名为 HelloWorldController.cs 的新文件,以及一个新文件夹 Views\HelloWorld。 控制器在 IDE 中打开。

显示已打开的 Hello World 控制器 .cs 选项卡的屏幕截图。在解决方案资源管理器中,Hello World 控制器 .cs 子文件夹和 Hello World 子文件夹被红色圆圈标出。

将文件的内容替换为以下代码。

using System.Web;
using System.Web.Mvc; 
 
namespace MvcMovie.Controllers 
{ 
    public class HelloWorldController : Controller 
    { 
        // 
        // GET: /HelloWorld/ 
 
        public string Index() 
        { 
            return "This is my <b>default</b> action..."; 
        } 
 
        // 
        // GET: /HelloWorld/Welcome/ 
 
        public string Welcome() 
        { 
            return "This is the Welcome action method..."; 
        } 
    } 
}

控制器方法将返回 HTML 字符串作为示例。 控制器已命名 HelloWorldController ,第一个方法命名 Index。 让我们从浏览器调用它。 运行应用程序(按 F5 或 Ctrl+F5)。 在浏览器中,将“HelloWorld”追加到地址栏中的路径。 (例如,在下图中,它是 http://localhost:1234/HelloWorld.)浏览器中的页面将类似于以下屏幕截图。 在上述方法中,代码直接返回字符串。 你告诉系统只返回一些简单的 HTML, 它做到了!

显示“本地主机”选项卡的屏幕截图,其中包含文本“这是我在窗口中的默认操作”。

ASP.NET MVC 会根据传入 URL 调用不同的控制器类(以及其中的不同操作方法)。 ASP.NET MVC 使用的默认 URL 路由逻辑使用以下格式来确定要调用的代码:

/[Controller]/[ActionName]/[Parameters]

App_Start/RouteConfig.cs 文件中设置路由的格式。

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 段时,默认为“Home”控制器和上述代码的默认值部分中指定的“Index”操作方法。

URL 的第一部分确定要执行的控制器类。 因此 /HelloWorld 映射到该 HelloWorldController 类。 URL 的第二部分确定要执行的类上的操作方法。 因此 /HelloWorld/Index 将导致 HelloWorldController 类的 Index 方法执行。 请注意,我们只需要浏览到 /HelloWorld ,并且 Index 该方法默认使用。 这是因为命名 Index 的方法是默认方法,如果未显式指定,则会在控制器上调用该方法。 URL 段的第三部分 (Parameters) 针对的是路由数据。 本教程稍后将介绍路由数据。

浏览到 http://localhost:xxxx/HelloWorld/WelcomeWelcome 方法运行并返回字符串“这是 Welcome 操作方法...”。 默认的 MVC 映射为 /[Controller]/[ActionName]/[Parameters]。 对于此 URL,使用 HelloWorld 作为控制器,Welcome 作为动作方法。 目前尚未使用 URL 的 [Parameters] 部分。

显示本地主机选项卡的屏幕截图,其中包含文本“这是窗口中的欢迎操作方法”。

让我们稍微修改一下示例,以便可以将某些参数信息从 URL 传递到控制器(例如 /HelloWorld/Welcome?name=Scott&numtimes=4)。 将Welcome方法更改为包含两个参数,如下所示。 请注意,如果未为该参数传递任何值,则代码使用 C# 可选参数功能来 numTimes 指示参数应默认为 1。

public string Welcome(string name, int numTimes = 1) {
     return HttpUtility.HtmlEncode("Hello " + name + ", NumTimes is: " + numTimes);
}

注释

安全说明:上述代码使用 HttpUtility.HtmlEncode 来保护应用程序免受恶意输入(即 JavaScript)的影响。 有关详细信息 ,请参阅如何:通过将 HTML 编码应用于字符串来保护 Web 应用程序中的脚本攻击

运行应用程序并浏览到示例 URL(http://localhost:xxxx/HelloWorld/Welcome?name=Scott&numtimes=4)。 可在 URL 中对 namenumtimes 使用其他值。 ASP.NET MVC 模型绑定系统会自动将地址栏中查询字符串中的命名参数映射到方法中的参数。

显示浏览器窗口的屏幕截图,其中 U R L 本地主机冒号 1 2 3 4 正斜杠 Hello World 正斜杠欢迎问号名称等于 Scott,编号等于 4。窗口中的文本为 Hello Scott Num Times 为 4。

在上面的示例中,不使用 Parameters URL 段(name),参数numTimes作为查询字符串传递。 ? 上述 URL 中的问号是分隔符,查询字符串如下。 "&" 字符分隔查询字符串。

将 Welcome 方法替换为以下代码:

public string Welcome(string name, int ID = 1)
{
    return HttpUtility.HtmlEncode("Hello " + name + ", ID: " + ID);
}

运行应用程序并输入以下 URL: http://localhost:xxx/HelloWorld/Welcome/1?name=Scott

显示浏览器窗口的屏幕截图,其中 U R L 本地主机冒号 1 2 3 4 正斜杠 Hello World 正斜杠欢迎正斜杠 1 问号名称等于 scott。窗口中的文本为 Hello Scott ID 1。

这一次,第三个 URL 段匹配路由参数 ID. 操作Welcome方法包含与方法中的 ID URL 规范匹配的参数(RegisterRoutes)。

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 }
    );
}

在 ASP.NET MVC 应用程序中,将参数作为路由数据(就像上述 ID 一样)传入参数比将参数作为查询字符串传递更为典型。 还可以添加路由,以将 namenumtimes 作为路由数据通过 URL 参数传递。 在 App_Start\RouteConfig.cs 文件中,添加“Hello”路由:

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 }
      );

      routes.MapRoute(
           name: "Hello",
           url: "{controller}/{action}/{name}/{id}"
       );
   }
}

运行应用程序并浏览到 /localhost:XXX/HelloWorld/Welcome/Scott/3

显示浏览器窗口的屏幕截图,其中 URL 本地主机冒号 1234 斜杠 Hello World 斜杠 Welcome 斜杠 Scott 斜杠 3。窗口中的文本为 你好 Scott (ID 3)。

对于许多 MVC 应用程序,默认路由可以正常工作。 您将在本教程中稍后学习如何通过模型绑定器传递数据,且你将无需修改默认路由。

在这些示例中,控制器一直在执行 MVC 的“VC”部分,即视图和控制器工作。 控制器将直接返回 HTML。 通常情况下,你不希望控制器直接返回 HTML,因为这会使编码变得非常繁琐。 相反,我们通常会使用单独的视图模板文件来帮助生成 HTML 响应。 接下来让我们看看如何做到这一点。