第1章 框架学习的基石与实战策略
第2章 大话ASP.NET Core 入门
第3章 创建最小(Minimal APIs)API应用程序
第4章 .NET 8.0 ASP.NET Core图书管理系统 :项目布局
在第3章中,我们利用ASP.NET Core的“空”模板创建了BookQuerySystem应用程序。这个模板为我们提供了一个简洁的基础架构,使得项目布局清晰易懂。首次运行并看到"Hello World"的那一刻,的确令人印象深刻。现在,让我们一起探讨一下这个项目的布局,了解其主要的文件和文件夹。
按"F5",你会看到"Hello World"的简单响应,这表明应用程序已经正确配置和运行。这个简洁的项目结构为后续添加功能和扩展提供了便利,无论是添加数据库连接、路由映射还是自定义中间件,都能轻松应对。
4.1.Program.cs文件
Program.cs文件是ASP.NET Core应用程序的入口文件,也是配置服务和中间件的主要场所。对于我们的BookQuerySystem图书管理系统应用程序,我们将在此文件中进行更多的配置和扩展,以满足应用程序的需求。
2021年前我写了一篇.NET 6.0 MVC图书查询系统的教程,由于.NET 6.0远远不如.NET8.0好用,所以那篇.NET6.0的教程1到现在还没更完!!! :)
4.1.1 入口点方法
在传统的 C# 程序中(C# 9 之前),Main 方法是程序的入口点。当你运行一个程序时, 运行时 2 (runtime)会查找 Main 方法并从那里开始执行代码。
然而,在使用顶级语句时,你不再显式定义 Main 方法。相反, 编译器3 会为你自动生成一个包含所有顶级语句的 Program 类和一个入口点方法。这个自动生成的方法充当程序的入口点,它的名称不再是 Main,而是一个由编译器生成的内部名称,你的代码无法直接引用这个名称。
4.1.2 顶级语句的工作原理
当你使用顶级语句编写程序时,编译器会将你的代码包装在一个自动生成的 Program 类中,并创建一个入口点方法(不是 Main),然后在这个方法内部执行你的顶级语句。这样,你就可以直接编写逻辑代码,而无需关心类的定义或 Main 方法的创建。
使用顶级语句的 C# 程序
Console.WriteLine("Hello World!");
编译器会将这段代码转换为类似于以下的形式:
class Program
{
static void <GeneratedEntryPointMethodName>()
{
Console.WriteLine("Hello World!");
}
}
< GeneratedEntryPointMethodName > 是一个由编译器生成的名称,它充当程序的入口点。
4.1.3 传统C#编写的程序入口点在.NET平台的结构
在传统C#编写的程序中,入口点通常是Program类中的Main方法定义的。
using System;
namespace BookQuerySystem
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Main方法中的args参数是一个字符串数组,它包含了传递给程序的命令行参数。这个args参数是由运行时环境提供的,它在程序的Main方法中可用。
命令行参数是指在操作系统命令行界面(如Windows的CMD或Linux的终端)中启动一个程序时,跟在程序名后面的额外信息。这些信息通常是以空格分隔的字符串,它们可以提供程序运行时的配置选项、文件路径或其他必要的数据。
这些参数通过Main方法的string[] args参数传递给程序。例如,如果你在命令行中运行以下命令:
BookQuerySystem.exe -input data.txt -verbose
这里,BookQuerySystem.exe是程序的名称,(-input ) ( data.txt) 和 (-verbose)是命令行参数。在程序的Main方法中,args数组会包含这些参数:
public static void Main(string[] args)
{
Console.WriteLine(args[0]); // 输出 "-input"
Console.WriteLine(args[1]); // 输出 "data.txt"
Console.WriteLine(args[2]); // 输出 "-verbose"
}
程序可以解析这些参数以决定执行什么操作,例如,-input用于指定要处理的文件,-verbose用于开启详细输出模式。在实际应用中,通常会使用条件语句或第三方库来解析和处理这些参数。
在顶级语句的上下文中,你可以直接访问它,因为编译器会自动为你处理所有的细节。
例如:
Console.WriteLine(args[0]); // 输出 "-input"
Console.WriteLine(args[1]); // 输出 "data.txt"
Console.WriteLine(args[2]); // 输出 "-verbose"
4.1.4在一个.NET应用程序中,只能有一个入口点
这通常对应于一个包含Main方法的文件。在引入顶级语句后,虽然不再需要显式声明Main方法,但这个限制仍然存在。这意味着在一个项目中,只能有一个包含顶级语句的源代码文件(通常是Program.cs或类似命名的文件),这个文件将会成为程序的入口点,编译器会自动处理顶级语句并生成内部的Main方法。
4.1.5 顶级语句与命名空间:在 ASP.NET Core 中使用最小API模式
顶级语句允许你在没有显式包含在任何特定命名空间中的情况下编写代码。这些语句默认处于全局命名空间中,特别适用于 ASP.NET Core等框架中的简单应用程序和最小API模式。
顶级语句与全局命名空间
顶级语句是不被任何类、结构或命名空间包围的代码行。在使用 ASP.NET Core 创建 Web 应用程序时,你通常会看到这样的顶级语句,它们用于配置和启动应用程序。
例如第3章中通过ASP.NET Core 空”模板创建的BookQuerySystem应用程序,目前你可以在Program.cs文件中看到四行代码(这四行代码在第3章已详细讲解):
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
这些代码中的每一行都是一个顶级语句,它们共同构成了应用程序的入口点。由于这些语句没有包含在任何命名空间内,因此它们属于全局命名空间。
结合使用顶级语句与命名空间
虽然顶级语句通常用于全局命名空间中的简单配置,但你也可以在相同的文件中定义命名空间和类型。这允许你将相关的数据和逻辑组织在一起,同时保持顶级语句的简洁性。
例如,你可以在全局命名空间中使用顶级语句来配置应用程序和定义数据模型,并在一个单独的命名空间中定义视图模型。
// 顶级语句,全局命名空间
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
// 数据模型,全局命名空间
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Classification { get; set; }
public string Author { get; set; }
public DateTime PublicationDate { get; set; }
public decimal Price { get; set; }
}
// 视图模型,特定命名空间
namespace BookQuerySystem.ViewModels
{
public class BookClassificationViewModel
{
public List<Book>? Books { get; set; }
public SelectList? Classifications { get; set; }
public string? BookClassification { get; set; }
public string? Search { get; set; }
}
}
顶级语句通常用于非常简单的程序或配置,而在实际的应用程序开发中,仍然推荐将逻辑组织在适当的文件和命名空间中,因此不建议将如下代码放在Program.cs文件中:
// 视图模型,特定命名空间
namespace BookQuerySystem.ViewModels
{
public class BookClassificationViewModel
{
public List<Book>? Books { get; set; }
public SelectList? Classifications { get; set; }
public string? BookClassification { get; set; }
public string? Search { get; set; }
}
}
你应该将视图模型放在专门的文件夹和命名空间中,例如创建一个 ViewModels 文件夹,并在其中创建一个名为 BookClassificationViewModel.cs 的文件,类名有点长!好在易懂,请不要着急,至于这个类是用来做什么的,我们以后早晚会讲到。
最小API模式
在 ASP.NET Core 中,最小API模式利用顶级语句和全局命名空间来创建简洁的 HTTP API/Web API。这种模式特别适用于微服务架构和需要快速开发的场景。
通过结合使用顶级语句和命名空间,你可以:
- 保持代码的简洁性和可读性。
- 快速定义和实现 Web API 端点。
- 将相关数据和逻辑组织在命名空间中,以便于维护和扩展。
顶级语句和命名空间提供了灵活的方式来组织代码。在 ASP.NET Core 框架中,合理利用这些特性可以帮助你创建简洁、高效且易于维护的应用程序。尽管顶级语句很方便,但合理使用命名空间仍然是组织代码和避免命名冲突的重要策略。
4.2 appsettings.json文件
appsettings.json 文件在 ASP.NET Core 应用程序中扮演着重要的角色,它用于存储应用程序的配置设置。这些设置可以包括数据库连接字符串、日志级别、外部服务的 API 密钥等。在 BookQuerySystem 应用程序中,appsettings.json 文件同样被用来定义应用程序的一些基础配置。
下面是对 BookQuerySystem 应用程序中 appsettings.json`文件的详细解释:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Logging:
- LogLevel: 这个部分定义了应用程序的日志级别。日志级别决定了应用程序将记录哪些级别的日志信息。
- Default: “Information” 表示默认情况下,应用程序将记录所有级别为“Information”及以上的日志信息(即 Information、Warning、Error、Critical)。
- Microsoft.AspNetCore: “Warning” 表示对于 Microsoft.AspNetCore 命名空间下的日志,只记录级别为“Warning”及以上的日志信息。(级别越往下越详细)
- LogLevel: 这个部分定义了应用程序的日志级别。日志级别决定了应用程序将记录哪些级别的日志信息。
AllowedHosts:
- " * “: 这个设置定义了应用程序可以接受的主机头(Host Header)。” * " 表示应用程序可以接受来自任何主机头的请求。在生产环境中,你应该将这个设置限制为你的应用程序实际部署的主机名,以增强安全性。
4.2.1 如何使用 appsettings.json
创建和配置 appsettings.json:
- 在你的 ASP.NET Core 项目中,确保有一个 appsettings.json文件。
- 在文件中添加你需要的配置设置,比如日志级别、数据库连接字符串等。
读取配置:
- 在你的应用程序中,你可以使用 IConfiguration接口来读取 appsettings.json文件中的配置设置。
- 例如,在 Program.cs 文件中,你可以通过依赖注入来获取 IConfiguration 实例,并使用它来读取配置值。
环境特定的配置:
- 你可以创建环境特定的配置文件,如 appsettings.Development.json 和 appsettings.Production.json,来存储不同环境下的配置设置。
- ASP.NET Core 会根据当前的环境变量自动选择正确的配置文件。
保护敏感配置:
- 对于包含敏感信息的配置设置,如数据库密码或 API 密钥,你应该使用安全的存储机制,如 Azure Key Vault 或环境变量。
- 避免在 appsettings.json 文件中直接存储敏感信息。
4.2.2 依赖注入
在 ASP.NET Core 应用程序中,依赖注入(DI)是一种核心的设计模式,它允许你在运行时将依赖项(如服务、配置等)自动传入到类中。IConfiguration 是一个用于访问应用程序配置设置的接口,通常这些设置存储在 appsettings.json 文件中。
在 Program.cs 文件中, ASP.NET Core 的框架已经完成了大部分工作,当你调用 WebApplication.CreateBuilder(args) 方法时,它会自动配置 IConfiguration 和其他基础服务(他们都是框架内置的,开发者无须手动管理和初始化)。
要在代码中使用 IConfiguration,你只需要在需要它的类中添加一个构造函数参数,或直接在路由处理程序(即 lambda 表达式或委托)中注入IConfiguration服务 。ASP.NET Core 的依赖注入系统就会自动为你提供 IConfiguration 的实例。
下面是一个更简单的例子,展示了如何在 ASP.NET Core 最小 API 中使用依赖注入来获取 IConfiguration 实例,并读取配置文件中的一个简单设置。
修改 appsettings.json 文件如下:
{
"BookQuerySystemSettings": {
"Greeting": "Hello from configuration!"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
然后在 Program.cs 文件中这样使用依赖注入来获取 IConfiguration 并读取 “BookQuerySystemSettings:Greeting” 的值:
using System.ComponentModel.DataAnnotations;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 使用依赖注入获取 IConfiguration 实例,并读取 Greeting 设置
app.MapGet("/greeting", (IConfiguration config) =>
{
// 读取 BookQuerySystemSettings:Greeting 设置
var greeting = config["BookQuerySystemSettings:Greeting"];
return greeting ?? "Greeting not found";
});
app.MapGet("/", () => "Hello World!");
app.Run();
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Classification { get; set; }
public string Author { get; set; }
public DateTime PublicationDate { get; set; }
public decimal Price { get; set; }
}
在这个例子中,我们定义了一个 /greeting 路由,它的处理程序接受一个 IConfiguration 参数。ASP.NET Core 的依赖注入系统会在运行时自动注入这个参数的一个实例。然后,我们使用索引器 config[“BookQuerySystemSettings:Greeting”] 来读取 “BookQuerySystemSettings:Greeting” 配置项的值,并将其作为响应返回。
如果你访问 /greeting 路由,你将看到从 appsettings.json 文件中读取的 “Hello from configuration!” 消息。如果你访问根路径 /,你将看到默认的 “Hello World!” 消息。
按"F5",你会看到"Hello World"的简单响应
在浏览器中访问https://localhost:7260/greeting你会看到下图:
前面说过我们定义了一个 /greeting 路由,它的处理程序接受一个 IConfiguration 参数。简单来说就是 /greeting 路由是通过app.MapGet(“/greeting”, (IConfiguration config) => {…})定义的。当你在浏览器中访问https://localhost:7260/greeting时,这个 URL4 会触发定义好的处理程序,即传入IConfiguration实例的lambda表达式。
该处理程序会读取配置中的BookQuerySystemSettings:Greeting键的值,并将其返回作为HTTP响应。如果找不到该配置键,它会返回一个默认的字符串“Greeting not found”。
注意,实际的端口号7260是随机的,会根据你的应用程序配置和本地设置有所不同。当你启动一个ASP.NET Core应用时,控制台会输出实际监听的URL,包括端口号。确保使用正确的端口号来访问你自己的应用程序。
4.3 launchSettings.json文件
在 ASP.NET Core 项目中,launchSettings.json文件扮演着至关重要的角色,它详细定义了应用程序在开发环境下的启动配置。这个文件位于项目的 Properties文件夹内。通过精心配置这个文件,你可以轻松地控制应用程序的运行方式,包括它监听的端口号、是否启用 SSL 加密、以及环境变量的设置等。
launchSettings.json文件中的配置只在开发环境中有效。当应用程序部署到生产环境时,通常会使用不同的配置来源,比如appsettings.json和appsettings.{Environment}.json文件,以及环境变量或配置服务器。生产环境的配置不会受到launchSettings.json的影响,除非你特别将这些设置迁移到生产环境中。
常见托管环境:
开发环境(Development Environment):
- 开发环境是程序员编写和测试代码的地方。在这里,开发者可以自由地实验、调试和修复错误,而不必考虑性能优化或安全性。launchSettings.json文件中的配置就是针对这种环境的,它允许开发者快速启动应用并进行调试,比如设置特定的端口、启用详细日志等。
- 在开发环境中,为了方便调试,通常会使用更宽松的安全策略和显示详细的错误信息。
预生产环境(Staging or Pre-Production Environment):
- 预生产环境是部署新代码或应用更新前的最后一步,它用于模拟生产环境,但不对外公开。这个环境用于验证新功能、性能优化和最终的用户验收测试。预生产环境的配置通常与生产环境一致,以便于发现问题并解决。
生产环境(Production Environment):
- 生产环境是应用正式对外提供服务的环境。这里的配置需要考虑性能、安全性和稳定性。应用程序在生产环境中通常部署在高可用的服务器集群上,以确保服务的连续性和可靠性。
- 生产环境的配置通常来自appsettings.json文件,以及appsettings.Production.json(或其他特定环境的文件,如appsettings.Staging.json)。这些文件包含了生产环境中应用需要的配置,如数据库连接字符串、API密钥、服务端口等。
- 生产环境还会使用环境变量来存储敏感信息,如API密钥或数据库密码,这样可以避免把这些信息直接写入代码或配置文件中,提高安全性。
- 此外,生产环境可能还使用配置服务器(如Azure App Configuration或Consul)来集中管理配置,这有助于动态更新配置,而无需重新部署应用。
4.3.1 launchSettings.json 文件结构
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:64271",
"sslPort": 44318
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5035",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7260;http://localhost:5035",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
launchSettings.json文件的结构清晰明了,主要包含以下几个核心部分:
$schema:
- 这是一个指向 JSON 模式文件的 URL,它用于验证 launchSettings.json文件的格式是否正确。
- 借助这个模式文件,你可以确保你的配置文件符合预期的格式规范。
iisSettings:
- 这部分专门用于配置 IIS Express 的相关参数。
- windowsAuthentication:一个布尔值,用于指定是否启用 Windows 身份验证机制。
- anonymousAuthentication:同样是一个布尔值,用于控制是否允许匿名访问。
- iisExpress:这是一个嵌套的对象,它进一步定义了 IIS Express 的具体设置,如应用程序的 URL 和 SSL 端口号等。
profiles:
- 这是 launchSettings.json 文件中最关键的部分,它包含了多个启动配置,每个配置都对应着应用程序的一种启动方式。
- 常见的配置有 http、https 和 IIS Express,它们分别定义了应用程序在 HTTP 协议、HTTPS 协议以及 IIS Express 上的启动行为。
4.3.2 profiles 部分详解
profiles 部分是 launchSettings.json 文件的核心,它包含了多个启动配置,每个配置都详细定义了应用程序的启动参数。
http 配置:
- commandName:指定了启动命令,对于 ASP.NET Core 应用程序来说,通常是 “Project”。
- dotnetRunMessages:一个布尔值,用于控制是否在控制台输出 dotnet 运行时的消息。
- launchBrowser:另一个布尔值,用于指定是否在应用程序启动时自动打开浏览器并导航到应用程序的 URL。
- applicationUrl:定义了应用程序的 URL,它指定了应用程序监听的端口号和路径。
- environmentVariables:一个对象,用于定义环境变量。例如,你可以将 ASPNETCORE_ENVIRONMENT 设置为 “Development”,以指示应用程序运行在开发环境下。
https 配置:
- 它与 http 配置非常相似,但主要用于配置应用程序在 HTTPS 协议下的启动行为。
- applicationUrl 字段同时包含了 HTTPS 和 HTTP 的 URL,以确保应用程序能够同时处理加密和非加密的请求。
IIS Express 配置:
- 它指定了使用 IIS Express 作为托管服务器时的启动配置。
- commandName 被设置为 “IISExpress”,以区分于其他启动命令。
- launchBrowser 和 environmentVariables 字段的含义与前面提到的配置相同。
- IIS Express 配置文件只能在 Windows 上使用,并使用 IIS Express 来运行你的应用。
4.3.3 ASP.NET Core中的Kestrel
第3章我们讲过 WebApplication.CreateBuilder(args) 方法执行了多个关键任务,构建了一个完整的ASP.NET Core应用程序的基础设施:
初始化服务容器:它创建了一个依赖注入容器,这个容器被称为服务容器或服务提供者,它负责管理应用程序组件之间的依赖关系,确保在需要时能够提供所需的服务,如数据库连接对象、中间件和其他工具类。
配置日志系统:方法内初始化了日志框架,使得开发者能够在应用程序的各个部分轻松地记录诊断信息,包括调试消息、警告和错误,以支持故障排查和性能分析。
设置应用主机和配置:该方法还配置了应用程序的主机,这是运行Web应用的基础。它包括定义应用程序的入口点、选择HTTP服务器(如Kestrel)以及设置访问应用的URL等网络配置。
提供扩展点:WebApplicationBuilder类提供了丰富的扩展方法,允许开发者进一步定制应用程序的行为,比如注册额外的服务、配置特定的日志提供者或是调整中间件顺序等。
构建WebApplication实例:通过调用Build()方法,WebApplicationBuilder构建了一个WebApplication实例,这个实例包含了所有配置和服务,是实际运行Web应用的对象。它准备好了接收和处理HTTP请求,执行业务逻辑,并返回响应。
我们之所以重提Kestrel,是因为它在理解ASP.NET Core的工作原理中至关重要。你是否好奇,当按下“F5”键启动项目时,背后隐藏着怎样一套有序的执行流程呢?
控制台应用程序的基础
在.NET环境中,控制台应用程序是一种基于命令行界面的程序,它通常没有图形用户界面(GUI)。在ASP.NET Core中,应用程序的入口点是一个Main方法,这个方法通常位于一个名为Program.cs的文件中。另一种情况是当你使用顶级语句编写程序时,编译器会将你的代码包装在一个自动生成的 Program 类中,并创建一个入口点方法(不是 Main)。无论那种情况都使得ASP.NET Core应用程序在结构上类似于控制台应用程序。
Web服务器的托管
ASP.NET Core应用程序不依赖于IIS(Internet Information Services)或任何其他外部Web服务器来运行。相反,它们自己托管一个Web服务器,默认情况下是Kestrel。Kestrel是一个跨平台的Web服务器,提供了高性能和异步I/O操作。
Kestrel的特点
- 跨平台:Kestrel可以在Windows、Linux和macOS上运行。
- 高性能:经过优化以处理高并发连接和低延迟请求。
- 轻量级:资源消耗低,适用于资源受限的环境。
- 安全性:支持HTTPS并经过强化以抵御Web服务器漏洞。
直接处理请求
当ASP.NET Core应用程序启动时,它会配置并启动Kestrel服务器,监听来自客户端(如Web浏览器)的HTTP请求。一旦请求到达,Kestrel会将其转发给ASP.NET Core的中间件管道进行处理。中间件管道是一系列中间件组件的集合,它们按照特定的顺序处理请求,并最终生成响应。
部署选项
虽然ASP.NET Core应用程序可以自己托管Kestrel服务器,但在生产环境中,通常会将Kestrel与反向代理服务器(如IIS、Nginx或Apache)结合使用。反向代理服务器负责接收来自互联网的请求,并将其转发给Kestrel服务器。这种配置可以提供额外的安全性、负载均衡和静态文件服务等功能。
当ASP.NET Core应用程序启动时,可以将其看成一个类似俄罗斯套娃样式的层次结构,最外层是控制台应用程序,它负责启动和托管整个应用程序。控制台应用程序会启动并托管自托管的Kestrel服务器,而Kestrel服务器则负责承载ASP.NET Core的中间件管道和应用程序逻辑。
“托管自托管的Kestrel服务器”可能听起来有些矛盾,但实际上它指的是一种应用程序架构模式,特别是在控制台应用程序中运行Web服务器的情况。这里的“自托管”和“托管”分别指的是两个不同的概念:
自托管(self-hosted):Kestrel服务器可以作为应用程序的一部分直接运行,不需要像传统的Web服务器那样在独立的服务器进程中运行。这意味着你可以在控制台应用、Windows服务、后台工作器等任何.NET 应用类型中直接启动Kestrel,使Web服务器成为应用程序自身的一个组成部分。
托管(hosting):另一方面,“托管”在这里指的是控制台应用程序作为宿主,它负责启动、停止和管理Kestrel服务器的生命周期。控制台应用程序不仅启动Kestrel,还会处理如异常捕获、日志记录、应用配置等任务,确保Kestrel在一个适当的环境中运行。
因此,当说“控制台应用程序会启动并托管自托管的Kestrel服务器”,实际上是在描述一个控制台应用如何承载和管理一个嵌入式Web服务器(Kestrel)的生命周期,使其能够处理HTTP请求并提供Web服务。
4.3.4 如何使用 launchSettings.json
端口号是计算机上用于区分不同网络服务的数字标识,端口号的选择通常是任意的,但有一些常见的端口号被约定用于特定的服务。例如,HTTP 服务通常使用端口 80,而 HTTPS 服务通常使用端口 443。然而,在开发环境中,你可以任意选择使用不同的端口号,以避免与计算机上运行的其他服务发生冲突。
当你使用 Visual Studio 启动 ASP.NET Core 应用程序时,launchSettings.json 文件中的配置将被自动读取并应用。你可以根据需要自由地修改这些配置,以适应你的开发需求。
如果你想要更改应用程序的端口号,只需在 http 或 https 配置的 applicationUrl 字段中指定新的端口号即可。例如:我们把https 配置的 applicationUrl 字段7260改为5000。
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:5000;http://localhost:5035",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
然后重新启动项目如图:
4.4 .csproj项目文件
.csproj 文件是 ASP.NET Core项目中的一个关键文件,它包含了项目的配置信息和元数据。当你双击解决方案资源管理器中的项目 BookQuerySystem时,Visual Studio 会允许你编辑该项目的 .csproj 文件。
4.4.1 .csproj 文件基础
.csproj 文件是一个 XML 文件,它定义了项目的编译选项、依赖项、目标框架等信息。在 ASP.NET Core 项目中,这个文件尤为重要,因为它指导 MSBuild(.NET 的构建系统)如何构建和打包你的应用程序。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
<Project Sdk=“Microsoft.NET.Sdk.Web”>: 这一行指定了项目使用的 SDK 是 Microsoft.NET.Sdk.Web。这个 SDK 专门为 ASP.NET Core Web 应用程序设计,提供了构建、运行和发布 Web 应用程序所需的一切。
<PropertyGroup>: <PropertyGroup> 元素包含了一组键值对,这些键值对定义了项目的全局属性。
<TargetFramework>net8.0</TargetFramework>: 这指定了项目的目标框架是 .NET 8.0。目标框架决定了项目将使用哪个版本的 .NET 库和运行时。在BookQuerySystem中,项目被配置为使用 .NET 8.0,这意味着它将能够利用该版本提供的所有新特性和改进。
<Nullable>enable</Nullable>: 这启用了 C# 8.0 引入的可空引用类型特性。当设置为 enable 时,编译器会强制你明确指定引用类型的可空性。
<ImplicitUsings>enable</ImplicitUsings>: 在 C# 10 中引入的隐式 using 指令允许你省略一些常用的命名空间引用,如 System 和 System.Collections.Generic。当 设置为 enable 时,这些隐式 using 指令会被添加到项目的编译上下文中,从而简化代码。
4.4.2 编辑 .csproj 文件
虽然通常不需要经常编辑 .csproj 文件,但在某些情况下(如添加新的依赖项、配置特定构建选项等),你可能需要直接编辑它。以下是一些编辑 .csproj 文件的建议:
使用 Visual Studio:双击项目BookQuerySystem节点在解决方案资源管理器中打开 .csproj 文件,并进行必要的更改。Visual Studio 提供了语法高亮和智能感知,使编辑过程更加容易。
手动编辑:你也可以使用任何文本编辑器(如 Notepad++、Visual Studio Code 等)来编辑 .csproj 文件。但是,请确保你了解 XML 语法和 .csproj 文件的特定结构。
添加依赖项:如果你需要添加 NuGet 包或其他项目依赖项,可以使用 Visual Studio 的 NuGet 包管理器 GUI,也可以直接在 .csproj 文件中添加 <ItemGroup> 元素和相应的 <PackageReference>或 <ProjectReference>元素。
提交更改:如果你正在使用版本控制系统(如 Git),请确保在提交更改前仔细检查 .csproj 文件,以确保没有引入不必要的错误或不一致性。
在添加依赖项时,最好使用 Visual Studio 的 NuGet 包管理器 GUI,因为它提供了更直观的界面和错误检查功能。
通过理解 .csproj 文件的结构和内容,你可以更好地控制 ASP.NET Core 项目的构建和打包过程。
总结
在本章中,我们深入探讨了ASP.NET Core图书管理系统(BookQuerySystem)的项目布局和关键文件。我们首先从Project.cs文件开始,了解了它是如何作为应用程序的入口点,并配置服务和中间件的。接着,我们详细解释了顶级语句的工作原理,以及它们如何在简化代码结构的同时保持应用程序的灵活性和可扩展性。
然后,我们讨论了appsettings.json文件的重要性,它用于存储应用程序的配置设置,如日志级别和允许的主机名。我们学习了如何使用IConfiguration接口在代码中读取这些配置值,并了解了如何创建环境特定的配置文件来管理不同环境下的配置。
此外,我们还介绍了launchSettings.json文件,它详细定义了应用程序在开发环境下的启动配置,包括监听的端口号、是否启用SSL加密等。我们解释了如何修改这些配置以适应开发需求,并了解了ASP.NET Core中的Kestrel服务器是如何作为自托管的Web服务器来工作的。
最后,我们探讨了.csproj项目文件,它是构建和打包ASP.NET Core应用程序的关键。我们了解了.csproj文件的结构和内容,包括目标框架、可空引用类型和隐式using指令等配置选项。我们还提供了编辑.csproj文件的建议,以便在需要时添加新的依赖项或配置特定的构建选项。
.NET 6.0 MVC图书查询系统的教程链接:https://blog.csdn.net/baidu_38495508/article/details/121731637 ↩︎
运行时是指程序执行时依赖的环境,它提供内存管理、垃圾回收等核心服务。在C#中,这涉及到.NET运行时(也称为CLR),它是.NET Framework和.NET的一部分。C#代码通过编译器(如csc.exe)被编译成中间语言(IL)代码,并打包进程序集(.exe或.dll文件)。在程序执行时,.NET运行时加载这些程序集,并使用即时编译器(JIT)将IL编译为针对当前运行平台的机器码,然后执行这些机器码。 ↩︎
这里的编译器指的是C#编译器,也称为csc.exe,它是Microsoft.NET SDK的一部分,负责将C#源代码编译成IL(中间语言)代码,然后再由.NET运行时(runtime)处理。在C# 9及更高版本中,如果使用了顶级语句,编译器会在编译过程中自动创建一个包含顶级语句的类(通常是Program类)以及一个内部的静态方法作为入口点,这个方法不是显式在源代码中定义的Main方法,而是由编译器生成的一个内部名称的方法。这个过程简化了源代码的结构,让开发者可以更加专注于编写业务逻辑,而不必关心程序的入口点。 ↩︎
URL(Uniform Resource Locator)和路由(Routing)在Web开发中是相关的概念,但不完全相同。
URL是统一资源定位符,它是互联网上资源的唯一地址,包括协议(如http或https),服务器地址,以及用于定位特定资源的路径。例如:
https://www.example.com/path/to/page
URL用于在Web浏览器中输入,以便访问特定的网络资源。
路由,特别是在ASP.NET Core这样的Web框架中,是服务器内部的一种机制,用于将HTTP请求映射到对应的处理程序,如控制器方法或API端点。路由定义了URL模式,并决定哪些URL请求应该由哪个处理程序来处理。在ASP.NET Core中,你可以使用MapGet, MapPost等方法来定义路由规则。
所以,虽然URL和路由紧密相关,但它们是不同的概念。URL是用户在浏览器中看到的地址,而路由是服务器内部用于解析和处理URL的逻辑。 ↩︎