选择使用新框架进行学习和开发是一项巨大的投资,因此尽早确定它是否适合您非常重要。 在本章中,我将介绍 ASP.NET Core 的一些背景知识:它是什么、它是如何工作的,以及为什么应该考虑将它用于构建 Web 应用程序。

如果您是 .NET 开发的新手,本章将帮助您了解 .NET 环境。 对于现有的 .NET 开发人员,我提供了关于现在是否是考虑将注意力转移到 .NET Core 和 .NET 5.0 的合适时机,以及 ASP.NET Core 相对于以前版本的 ASP.NET 可以提供的优势的指导。

在本章结束时,您应该对 .NET 环境、.NET 5.0 的作用以及 ASP.NET Core 工作原理的基本机制有一个很好的了解——所以事不宜迟,让我们开始吧!

ASP.NET Core 是一个跨平台、开源的 Web 应用程序框架,可用于快速构建动态的、服务器端呈现的应用程序。 您还可以使用 ASP.NET Core 创建可供移动应用程序、基于浏览器的单页应用程序(如 Angular 和 React)或其他后端应用程序使用的 HTTP API。

ASP.NET Core 提供了用于构建应用程序的结构、辅助函数和框架,这样您就不必自己编写大量此类代码。 然后,ASP.NET Core 框架代码调用您的“处理程序”,该处理程序又调用应用程序业务逻辑中的方法,如图 1.1 所示。 此业务逻辑是您的应用程序的核心。 您可以在此处与其他服务交互,例如数据库或远程 API,但您的业务逻辑通常不直接依赖于 ASP.NET Core。

图 1.1 一个典型的 ASP.NET Core 应用程序由几个层组成。 ASP.NET Core 框架代码处理来自客户端的请求,处理复杂的网络代码。 然后,框架调用您使用框架提供的原语编写的处理程序(Razor 页面和 Web API 控制器)。 最后,这些处理程序调用应用程序的域逻辑,这些逻辑通常是 C# 类和对象,没有任何 ASP.NET Core 特定的依赖项。

使用web框架

如果您不熟悉 Web 开发,那么进入一个拥有如此多流行语和大量不断变化的产品的领域可能会令人生畏。 您可能想知道它们是否都是必需的——从服务器返回文件有多难?

好吧,完全可以在不使用 Web 框架的情况下构建静态 Web 应用程序,但它的功能将受到限制。 一旦你想提供任何一种安全感或活力,你可能会遇到困难,而最初吸引你的简单性将在你眼前消失。

正如桌面或移动开发框架可以帮助您构建本机应用程序一样,与尝试从头开始构建所有内容相比,ASP.NET Core 使编写 Web 应用程序更快、更容易、更安全。 它包含用于常见事物的库,例如

  • 创建动态变化的网页
  • 让用户登录您的网络应用程序
  • 让用户使用他们的 Facebook 帐户使用 OAuth 登录到您的 Web 应用程序
  • 为构建可维护的应用程序提供通用结构
  • 读取配置文件
  • 提供图像文件
  • 记录对您的 Web 应用程序的请求
  • 任何现代 Web 应用程序的关键是生成动态网页的能力。动态网页可能会根据当前登录的用户显示不同的数据,也可能会显示用户提交的内容。 如果没有动态框架,就无法登录网站或在页面上显示任何类型的个性化数据。 简而言之,像 Amazon、eBay 和 Stack Overflow(如图 1.2 所示)这样的网站是不可能的。

    图 1.2 Stack Overflow 网站 ( https://stackoverflow.com ) 是使用 ASP.NET 构建的,几乎完全是动态内容。
  • 适用于当前Web开发趋势,例如客户端应用程序和部署到云环境
  • 为了实现所有这些目标,Microsoft 需要一个平台,该平台可以提供底层库来创建基本对象(如列表和字典),以及执行简单的文件操作等。 到目前为止,ASP.NET 开发一直集中并依赖于仅限 Windows 的 .NET 框架。 对于 ASP.NET Core,微软创建了一个在 Windows、Linux 和 macOS 上运行的轻量级平台,称为 .NET Core(以及随后的 .NET 5.0),如图 1.3 所示。

    .NET Core(及其后续版本 .NET 5.0)使用许多与 .NET Framework 相同的 API,但它更加模块化,并且仅实现了 .NET Framework 所具有的功能的子集,目标是提供更简单的实现和编程 模型。 它是一个完全独立的平台,而不是 .NET Framework 的一个分支,尽管它的许多 API 使用类似的代码。

    仅使用 .NET 5.0,就可以构建运行跨平台的控制台应用程序。微软创建 ASP.NET Core 作为控制台应用程序之上的附加层,因此转换为 Web 应用程序涉及添加和组合库,如图所示 1.4.

    图 1.3 ASP.NET Core、ASP.NET、.NET Core/.NET 5.0、.NET Framework 之间的关系。 ASP.NET Core 运行在 .NET Core 和 .NET 5.0 上,因此可以跨平台运行。相反,ASP.NET 仅在 .NET Framework 上运行,因此它与 Windows 操作系统绑定。

    通过将 ASP.NET Core Web 服务器添加到您的 .NET 5.0 应用程序,您的应用程序可以作为 Web 应用程序运行。 ASP.NET Core 由许多小型库组成,您可以从中进行选择,为您的应用程序提供不同的功能。 你很少需要所有可用的库,你只添加你需要的。 一些库是常见的,几乎会出现在您创建的每个应用程序中,例如用于读取配置文件或执行日志记录的库。 其他库建立在这些基本功能之上,以提供特定于应用程序的功能,例如通过 Facebook 或 Google 进行第三方登录。

    何时选择 ASP.NET Core

    您可以构建什么类型的应用程序?

    ASP.NET Core 提供了一个通用的 Web 框架,可用于各种应用程序。 它最明显可以用于构建丰富的动态网站,无论它们是电子商务网站、基于内容的网站还是大型 n 层应用程序——与以前的 ASP.NET 版本非常相似。

    最初发布 .NET Core 时,很少有第三方库可用于构建这些类型的复杂应用程序。 经过几年的积极发展,情况已不再如此。 许多开发人员更新了他们的库以使用 ASP.NET Core,并且创建了许多其他库以专门针对 ASP.NET Core。 例如,开源内容管理系统 (CMS) Orchard1 已重新开发为 Orchard Core2 以在 ASP.NET Core 上运行。 相比之下,cloudscribe CMS 项目(图 1.5)从一开始就是专门为 ASP.NET Core 编写的。

    图 1.5 .NET Foundation 网站 ( https://dotnetfoundation.org/ ) 是使用 cloudscribe CMS 和 ASP.NET Core 构建的。

    传统的基于页面的服务器端呈现的 Web 应用程序是 ASP.NET 开发的基础,无论是使用以前版本的 ASP.NET 还是使用 ASP.NET Core。 此外,使用通常与 REST 服务器通信的客户端框架的单页应用程序 (SPA) 可以通过 ASP.NET Core 轻松创建。 无论您使用的是 Angular、Vue、React 还是其他一些客户端框架,都可以轻松创建一个 ASP.NET Core 应用程序来充当服务器端 API。

    定义 REST 代表具象状态转移。 RESTful 应用程序通常使用轻量级和无状态的 HTTP 调用来读取、发布(创建/更新)和删除数据。

    ASP.NET Core 不限于创建 RESTful 服务。 根据您的要求,为您的应用程序创建 Web 服务或远程过程调用 (RPC) 样式的服务很容易,如图 1.6 所示。 在最简单的情况下,您的应用程序可能只公开一个端点,从而缩小其范围以成为微服务。由于其跨平台支持和轻量级设计,ASP.NET Core 非常适合构建简单的服务。

    图 1.6 ASP.NET Core 可以充当各种客户端的服务器端应用程序:它可以为传统 Web 应用程序提供 HTML 页面,它可以充当客户端 SPA 应用程序的 REST API,或者它可以充当 用于客户端应用程序的临时 RPC 服务。

    选择平台时应考虑多个因素,并非所有因素都是技术性的。 其中一个因素是您可以期望从其创建者那里获得的支持水平。 对于某些组织来说,这可能是采用开源软件的主要障碍之一。 幸运的是,微软已承诺在 .NET Core 和 ASP.NET Core 的长期支持 (LTS) 版本发布后至少三年内提供全面支持。 由于所有开发都是公开进行的,因此您有时可以从一般社区以及直接从 Microsoft 获得问题的答案。

    在决定是否使用 ASP.NET Core 时,您需要考虑两个主要方面:您是否已经是 .NET 开发人员,以及您是在创建新应用程序还是希望转换现有应用程序。

    如果您不熟悉 .NET 开发

    如果您是 .NET 开发新手并且正在考虑使用 ASP.NET Core,那么欢迎!微软正在推动 ASP.NET Core 作为 Web 开发初学者的一个有吸引力的选择,但采用 .NET 跨平台意味着它正在与许多其他框架竞争 在他们自己的地盘上。 与其他跨平台 Web 框架相比,ASP.NET Core 有很多卖点:

  • 它是一个现代、高性能、开源的 Web 框架。
  • 它使用熟悉的设计模式和范例。
  • C# 是一门很棒的语言(如果您愿意,也可以使用 VB.NET 或 F#)。
  • 您可以在任何平台上构建和运行。
  • ASP.NET Core 是对 ASP.NET 框架的重新构想,采用现代软件设计原则构建在新的 .NET Core/.NET 5.0 平台之上。 虽然从某种意义上说是新的,但 .NET Core 已经在生产中广泛使用了几年,并且很大程度上借鉴了已经使用了近二十年的成熟、稳定和可靠的 .NET Framework。 您可以高枕无忧,选择 ASP.NET Core 和 .NET 5.0,您将获得一个可靠的平台以及功能齐全的 Web 框架。

    当今可用的许多 Web 框架都使用类似的成熟设计模式,ASP.NET Core 也不例外。 例如,Ruby on Rails 以使用模型-视图-控制器 (MVC) 模式而闻名; Node.js 以其使用小型离散模块(称为管道)处理请求的方式而闻名; 依赖注入存在于各种各样的框架中。 如果您熟悉这些技术,您应该会发现将它们转移到 ASP.NET Core 很容易; 如果他们对您来说是新手,那么您可以期待使用行业最佳实践!

    .NET 开发的主要语言,尤其是 ASP.NET Core,是 C#。这种语言有大量的追随者,这是有充分理由的! 作为一种面向对象的基于 C 的语言,它为那些习惯于 C、Java 和许多其他语言的人提供了一种熟悉感。 此外,它还具有许多强大的功能,例如语言集成查询 (LINQ)、闭包和异步编程结构。 C# 语言也是在 GitHub 上公开设计的,微软的 C# 编译器也是如此,代号为 Roslyn。

    ASP.NET Core 和 .NET 5.0 的主要卖点之一是能够在任何平台上开发和运行。 无论您使用的是 Mac、Windows 还是 Linux,您都可以运行相同的 ASP.NET Core 应用程序并跨多个环境进行开发。作为 Linux 用户,支持广泛的发行版(RHEL、Ubuntu、Debian、CentOS、 Fedora 和 openSUSE 等等),因此您可以确信您选择的操作系统将是一个可行的选择。 ASP.NET Core 甚至可以在小型 Alpine 发行版上运行,以实现真正紧凑的容器部署。

    除了在每个平台上运行之外,.NET 的卖点之一是只编写和编译一次的能力。 您的应用程序被编译为中间语言 (IL) 代码,这是一种独立于平台的格式。 如果目标系统安装了 .NET 5.0 运行时,则可以从任何平台运行编译后的 IL。 这意味着您可以在 Mac 或 Windows 机器上进行开发,并将完全相同的文件部署到生产 Linux 机器上。 ASP.NET Core 和 .NET Core/.NET 5.0 终于实现了这种一次编译、随处运行的承诺。

    如果您是创建新应用程序的 .NET Framework 开发人员

    如果您是 .NET 开发人员,是否为新应用程序投资 ASP.NET Core 的选择主要是时间问题。 .NET Core 的早期版本缺少一些使其难以采用的功能。 随着 .NET Core 3.1 和 .NET 5.0 的发布,这不再是问题; Microsoft 现在明确建议所有新的 .NET 应用程序都应使用 .NET 5.0。 微软已承诺为旧的 ASP.NET 框架提供错误和安全修复,但不会提供更多功能更新。 .NET Framework 不会被删除,因此您的旧应用程序将继续工作,但您不应将其用于新开发。

    与以前的 ASP.NET 框架相比,ASP.NET Core 的主要优点是

  • 跨平台开发部署
  • 以性能为特征
  • 简化的托管模型
  • 定期发布,发布周期更短
  • 模块化功能
  • 作为 .NET 开发人员,如果您不使用任何特定于 Windows 的结构,例如注册表,那么构建和部署跨平台的能力打开了通往全新应用途径的大门:利用更便宜的 Linux VM 托管 在云中,使用 Docker 容器进行可重复的持续集成,或者在您的 Mac 上编写 .NET 代码,而无需运行 Windows 虚拟机。 ASP.NET Core 与 .NET 5.0 相结合,使这一切成为可能。

    .NET Core 和 .NET 5.0 本质上是跨平台的,但如果需要,您仍然可以使用特定于平台的功能。 例如,注册表或目录服务等 Windows 特定功能可以通过兼容包启用,使这些 API 在 .NET 5.0.6 中可用。它们仅在 Windows 上运行 .NET 5.0 时可用,而不是在 Linux 或 macOS 上运行, 因此,您需要注意此类应用程序仅在 Windows 环境中运行或考虑可能缺少的 API。

    以前的 ASP.NET 框架的托管模型是一个相对复杂的模型,依靠 Windows IIS 提供 Web 服务器托管。 在跨平台环境中,这种共生关系是不可能的,因此采用了另一种托管模型——将 Web 应用程序与底层主机分开。 这个机会促成了 Kestrel 的开发:一个可以运行 ASP.NET Core 的快速、跨平台的 HTTP 服务器。

    不同于之前的设计,即 IIS 调用应用程序的特定点,ASP.NET Core 应用程序是自托管 Web 服务器并直接处理请求的控制台应用程序,如图 1.7 所示。 这种托管模型在概念上要简单得多,允许您从命令行测试和调试应用程序,尽管它不一定消除在生产中运行 IIS(或等效)的需要,正如您将在第 1.3 节中看到的那样。

    图 1.7 ASP.NET(上)和 ASP.NET Core(下)中托管模型的区别。 使用以前版本的 ASP.NET,IIS 与应用程序紧密耦合。 ASP.NET Core 中的托管模型更简单; IIS 将请求交给 ASP.NET Core 应用程序中的自托管 Web 服务器并接收响应,但对应用程序没有更深入的了解。

    将现有 ASP.NET 应用程序转换为 ASP.NET Core

    与新应用程序相比,现有应用程序可能已经在提供价值,因此在从 ASP.NET 转换为 ASP.NET Core 过程中执行可能相当于重大重写的操作应该总能带来切实的好处。 采用 ASP.NET Core 的优势与新应用程序的优势大致相同:跨平台部署、模块化功能以及对性能的关注。 好处是否足够将在很大程度上取决于您的应用程序的细节,但有一些特征是明确的反对转换指标:

  • 您的应用程序使用 ASP.NET Web 窗体
  • 您的应用程序是使用 WCF 构建的
  • 你的应用程序很大,有很多“高级”的 MVC 特性
  • 如果您有 ASP.NET Web 窗体应用程序,则不建议尝试将其转换为 ASP.NET Core。 Web 窗体与 System.Web.dll 密不可分,因此可能永远不会在 ASP.NET Core 中可用。 将应用程序转换为 ASP.NET Core 将有效地涉及从头开始重写应用程序,不仅要转换框架,还要转换设计范式。 更好的方法是慢慢引入 Web API 概念,并尝试减少对 ViewData 等遗留 Web 表单结构的依赖。

    ASP.NET Core 仅部分支持 Windows Communication Foundation (WCF)。 可以使用一些 WCF 服务,但支持充其量是参差不齐。 没有支持从 ASP.NET Core 应用程序托管 WCF 服务的方法,因此如果您绝对必须支持 WCF,那么现在最好避免使用 ASP.NET Core。

    如果您现有的应用程序很复杂并且大量使用了以前的 MVC 或 Web API 扩展点或消息处理程序,那么将您的应用程序移植到 ASP.NET Core 可能会更加困难。 ASP.NET Core 构建了许多与之前版本的 ASP.NET MVC 相似的功能,但底层架构不同。 之前的一些功能没有直接替代品,因此需要重新考虑。

    应用程序越大,将应用程序转换为 ASP.NET Core 的难度就越大。 Microsoft 本身建议将应用程序从 ASP.NET MVC 移植到 ASP.NET Core 至少与从 ASP.NET Web 窗体移植到 ASP.NET MVC 一样大。 如果那不吓到你,那么什么都不会!

    如果一个应用程序很少使用,不属于你的核心业务,或者短期内不需要重大开发,我强烈建议你不要尝试将其转换为 ASP.NET Core。 Microsoft 将在可预见的未来支持 .NET Framework(Windows 本身就依赖它!),转换这些“边缘”应用程序的回报不太可能值得付出努力。

    那么,什么时候应该将应用程序移植到 ASP.NET Core? 正如我已经提到的,最好的入门机会是小型、新领域的新项目,而不是现有的应用程序。 也就是说,如果有问题的现有应用程序很小或者需要在未来进行重大开发,那么移植可能是一个不错的选择。在可能的情况下,最好在小迭代中工作,而不是尝试一次转换整个应用程序。 但是,如果您的应用程序主要由 MVC 或 Web API 控制器和关联的 Razor 视图组成,那么迁移到 ASP.NET Core 可能是一个不错的选择。

    ASP.NET Core 是如何工作的?

    到目前为止,您应该对 ASP.NET Core 是什么以及应该将其用于哪种应用程序有了一个很好的了解。 在本节中,您将了解使用 ASP.NET Core 构建的应用程序是如何工作的,从用户请求 URL 到在浏览器中显示的页面。 要到达那里,首先您将了解 HTTP 请求如何适用于任何 Web 服务器,然后您将了解 ASP.NET Core 如何扩展该过程以创建动态网页。

    HTTP Web 请求如何工作?

    如您所知,ASP.NET Core 是一个用于构建从服务器提供数据的 Web 应用程序的框架。 Web 开发人员最常见的场景之一是构建可以在 Web 浏览器中查看的 Web 应用程序。 图 1.8 显示了您可以从任何 Web 服务器获得的高级流程。

    图 1.8 请求网页。 用户首先请求一个网页,这会导致向服务器发送一个 HTTP 请求。 服务器解释请求,生成必要的 HTML,并在 HTTP 响应中将其发送回。 然后浏览器可以显示网页。

    当用户导航到网站或在浏览器中键入 URL 时,该过程就开始了。 URL 或 Web 地址由主机名和 Web 应用程序上某些资源的路径组成。 导航到浏览器中的地址会使用 HTTP 协议从用户的计算机向托管 Web 应用程序的服务器发送请求。

    请求通过互联网,可能到达世界的另一端,直到它最终到达与给定主机名关联的服务器,Web 应用程序在该服务器上运行。 请求可能会被多个路由器接收并重新广播,但只有当它到达与主机名关联的服务器时才会处理请求。

    一旦服务器接收到请求,它将检查请求是否有意义,如果是,它将生成 HTTP 响应。 根据请求,此响应可能是网页、图像、JavaScript 文件或简单的确认。 在这个例子中,我假设用户已经到达了一个 web 应用的主页,所以服务器用一些 HTML 来响应。 HTML 被添加到 HTTP 响应中,然后通过 Internet 发送回发出请求的浏览器。

    一旦用户的浏览器开始接收 HTTP 响应,它就可以开始在屏幕上显示内容,但 HTML 页面也可能会引用服务器上的其他页面和链接。 为了显示完整的网页,而不是静态、无色、原始的 HTML 文件,浏览器必须重复请求过程,获取每个引用的文件。 HTML、图像、用于样式的 CSS 和用于额外行为的 JavaScript 文件都是使用完全相同的 HTTP 请求过程获取的。

    互联网上发生的几乎所有交互都是同一基本过程的表面。 一个基本的网页可能只需要几个简单的请求就可以完全呈现,而一个现代的大型网页可能需要数百个。 例如,在撰写本文时,Amazon.com 主页 (www.amazon.com) 发出 606 个请求,其中包括 3 个 CSS 文件、12 个 JavaScript 文件和 402 个图像文件!

    ASP.NET Core 如何处理请求?

    当您使用 ASP.NET Core 构建 Web 应用程序时,浏览器仍将使用与以前相同的 HTTP 协议与您的应用程序通信。 ASP.NET Core 本身包含在服务器上为处理请求而发生的所有事情,包括验证请求是否有效、处理登录详细信息和生成 HTML。

    与通用网页示例一样,请求过程在用户浏览器向服务器发送 HTTP 请求时开始,如图 1.9 所示。

    图 1.9 ASP.NET Core 应用程序如何处理请求。 运行自托管 Web 服务器的 ASP.NET Core 应用程序接收到请求。 Web 服务器处理请求并将其传递给应用程序主体,应用程序主体生成响应并将其返回给 Web 服务器。 Web 服务器将此响应发送到浏览器。

    ASP.NET Core 应用程序从网络接收请求。 每个 ASP.NET Core 应用程序都有一个内置的 Web 服务器,默认情况下是 Kestrel,它负责接收原始请求并构造数据的内部表示形式,即 HttpContext 对象,可供应用程序的其余部分使用。

    从这个表示中,您的应用程序应该具有创建对请求的适当响应所需的所有详细信息。 它可以使用存储在 HttpContext 中的详细信息来生成适当的响应,这可能是生成一些 HTML、返回“拒绝访问”消息或发送电子邮件,这一切都取决于您的应用程序的要求。

    应用程序处理完请求后,会将响应返回给 Web 服务器。 ASP.NET Core Web 服务器会将表示形式转换为原始 HTTP 响应并将其发送到网络,网络会将其转发到用户的浏览器。

    对用户来说,这个过程似乎与图 1.8 中所示的通用 HTTP 请求相同——用户发送了一个 HTTP 请求并接收到了一个 HTTP 响应。所有不同之处都在您的应用程序中的服务器端。

    ASP.NET Core 和反向代理

    您可以将 ASP.NET Core 应用程序直接公开到 Internet,以便 Kestrel 直接从网络接收请求。 但是,在原始网络和您的应用程序之间使用反向代理更为常见。 在 Windows 中,反向代理服务器通常是 IIS,在 Linux 或 macOS 上,它可能是 NGINX、HAProxy 或 Apache。

    反向代理是负责接收请求并将其转发到适当的 Web 服务器的软件。 反向代理直接暴露给互联网,而底层 Web 服务器只暴露给代理。 这种设置有几个好处,主要是 Web 服务器的安全性和性能。

    您可能会认为拥有一个反向代理和一个 Web 服务器有点多余。为什么不拥有一个或另一个呢? 嗯,好处之一是您的应用程序与底层操作系统的解耦。 相同的 ASP.NET Core Web 服务器 Kestrel 可以跨平台并在各种代理后面使用,而不会对特定实现施加任何限制。 或者,如果您编写了一个新的 ASP.NET Core Web 服务器,您可以使用它来代替 Kestrel,而无需更改您的应用程序的任何其他内容。

    反向代理的另一个好处是它可以抵御来自公共互联网的潜在威胁。 他们通常负责其他方面,例如重新启动已崩溃的进程。 Kestrel 在反向代理后面使用时,可以保持简单的 HTTP 服务器,而不必担心这些额外的功能。 将其视为简单的关注点分离:Kestrel 关注生成 HTTP 响应; 反向代理负责处理与 Internet 的连接。

    你已经了解了请求和响应是如何在 ASP.NET Core 应用程序中往返的,但我还没有谈到响应是如何生成的。 在本书的第 1 部分中,我们将了解构成典型 ASP.NET Core 应用程序的组件以及它们如何组合在一起。 在 ASP.NET Core 中生成响应需要做很多事情,通常都在几分之一秒内完成,但是在本书的整个过程中,我们将逐步逐步完成一个应用程序,详细介绍每个组件。

  • ASP.NET Core 是一个以现代软件架构实践和模块化为重点的新型 Web 框架。
  • 它最适合用于新的“green-field”项目。
  • WCF 服务器和 Web 窗体等传统技术不能与 ASP.NET Core 一起使用。
  • ASP.NET Core 在跨平台的 .NET 5.0 平台上运行。 您可以使用 Windows 兼容包访问特定于 Windows 的功能,例如 Windows 注册表。
  • 获取网页涉及发送 HTTP 请求和接收 HTTP 响应。
  • ASP.NET Core 允许您动态构建对给定请求的响应。
  • ASP.NET Core 应用程序包含一个 Web 服务器,它充当请求的入口点。
  • ASP.NET Core 应用程序通常通过反向代理服务器保护互联网,该服务器将请求转发到应用程序。
  •