添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本文介绍如何将现有 ASP.NET Core 5.0 项目更新为 ASP.NET Core 6.0。 有关如何从 ASP.NET Core 3.1 迁移到 ASP.NET Core 6.0 的说明,请参阅 从 ASP.NET Core 3.1 迁移到 6.0 。

Visual Studio Visual Studio Code Visual Studio for Mac

更新 global.json 中的 .NET SDK 版本

如果依靠 global.json 文件来定向于特定 .NET SDK 版本,请将 version 属性更新为已安装的 .NET 6.0 SDK 版本。 例如:

"sdk": { - "version": "5.0.100" + "version": "6.0.100"

更新目标框架

将项目文件的 目标框架名字对象 (TFM) 更新为 net6.0 :

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
</Project>

更新包引用

在项目文件中,将每个 Microsoft.AspNetCore.* 和 Microsoft.Extensions.* 包引用的 Version 特性更新为 6.0.0 或更高版本。 例如:

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.3" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
</ItemGroup>

新托管模型

适用于 ASP.NET Core 的新的 .NET 6 最小托管模型只需要一个文件和几行代码。 迁移到 6.0 的应用不需要使用新的最小托管模型。 有关详细信息,请参阅以下部分中的迁移到 6.0 的应用不需要使用新的最小托管模型。

ASP.NET Core 空模板中的以下代码使用新的最小托管模型创建应用:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

最小托管模型:

  • 显著减少创建应用所需的文件和代码行数。 只需要一个文件和四行代码。
  • 将 Startup.cs 和 Program.cs 统一到单个 Program.cs 文件中。
  • 使用顶级语句最大程度减少应用所需的代码。
  • 使用全局 指令消除或最大程度减少所需的 语句行数。
  • 以下代码显示 ASP.NET Core 5 Web 应用模板 (Razor Pages) 中的 Startup.cs 和 Program.cs 文件,其中删除了未使用的 using 语句:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    // Unused usings removed.
    namespace WebAppRPv5
        public class Startup
            public Startup(IConfiguration configuration)
                Configuration = configuration;
            public IConfiguration Configuration { get; }
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
                services.AddRazorPages();
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                if (env.IsDevelopment())
                    app.UseDeveloperExceptionPage();
                    app.UseExceptionHandler("/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                app.UseHttpsRedirection();
                app.UseStaticFiles();
                app.UseRouting();
                app.UseAuthorization();
                app.UseEndpoints(endpoints =>
                    endpoints.MapRazorPages();
    
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Hosting;
    // Unused usings removed.
    namespace WebAppRPv5
        public class Program
            public static void Main(string[] args)
                CreateHostBuilder(args).Build().Run();
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                        webBuilder.UseStartup<Startup>();
    

    在 ASP.NET Core 6 中,上面的代码替换为以下内容:

    var builder = WebApplication.CreateBuilder(args);
    // Add services to the container.
    builder.Services.AddRazorPages();
    var app = builder.Build();
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.MapRazorPages();
    app.Run();
    

    上面的 ASP.NET Core 6 示例演示了以下操作方式:

  • ConfigureServices 替换为 WebApplication.Services。
  • builder.Build() 将配置的 WebApplication 返回到变量 app。 Configure 会替换为对使用 app 的相同服务的配置调用。
  • 本文档后面会提供使用最小托管模型将 ASP.NET Core 5 Startup 代码迁移到 ASP.NET Core 6 的详细示例。

    对为 Web 应用模板生成的其他文件进行了几处更改:

  • Index.cshtml 和 Privacy.cshtml 删除了未使用的 using 语句。
  • Error.cshtml 中的 RequestId 声明为空引用类型 (NRT):
  • - public string RequestId { get; set; }
    + public string? RequestId { get; set; }
    
  • 和 appsettings.Development.json中的appsettings.json日志级别默认值已更改:
  • - "Microsoft": "Warning",
    - "Microsoft.Hosting.Lifetime": "Information"
    + "Microsoft.AspNetCore": "Warning"
    

    在前面的 ASP.NET Core模板代码中, "Microsoft": "Warning" 已更改为 "Microsoft.AspNetCore": "Warning"。 此更改会导致记录命名空间中的所有信息性消息,Microsoft但除外Microsoft.AspNetCore。 例如,Microsoft.EntityFrameworkCore 现记录在信息级别。

    有关新托管模型的更多详细信息,请参阅常见问题解答部分。 有关采用 NRT 和 .NET 编译器 Null 状态分析的详细信息,请参阅空引用类型 (NRT) 和 .NET 编译器 Null 状态静态分析部分。

    迁移到或使用 6.0 及更高版本的应用不需要使用新的最小托管模型

    完全支持使用 Startup 以及由 ASP.NET Core 3.1 和 5.0 模板使用的通用主机。

    将 Startup 与新的最小托管模型结合使用

    ASP.NET Core 3.1 和 5.0 应用可以将其 Startup 代码与新的最小托管模型结合使用。 将 与最小托管模型配合使用 Startup 具有以下优点:

  • 没有隐藏的反射用于调用 Startup 类。
  • 可以编写异步代码,因为开发人员控制对 的 Startup调用。
  • 可以编写交错 和 Configure的代码ConfigureServices。
  • 将代码与新的最小托管模型配合使用 Startup 的一个次要限制是,若要将依赖项注入 到 Configure中,必须手动解析 中的 Program.cs 服务。

    请考虑由 ASP.NET Core 3.1 或 5.0 Razor Pages 模板生成的代码:

    public class Program
        public static void Main(string[] args)
            CreateHostBuilder(args).Build().Run();
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                    webBuilder.UseStartup<Startup>();
    
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
            services.AddRazorPages();
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(endpoints =>
                endpoints.MapRazorPages();
    

    上面的代码已迁移到新的最小托管模型:

    using Microsoft.AspNetCore.Builder;
    var builder = WebApplication.CreateBuilder(args);
    var startup = new Startup(builder.Configuration);
    startup.ConfigureServices(builder.Services);
    var app = builder.Build();
    startup.Configure(app, app.Environment);
    app.Run();
    
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
            services.AddRazorPages();
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            if (!env.IsDevelopment())
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(endpoints =>
                endpoints.MapRazorPages();
    

    在上面的代码中,删除了 if (env.IsDevelopment()) 程序块,因为在开发模式下,开发人员异常页中间件在默认情况下处于启用状态。 有关详细信息,请参阅下一部分中的 ASP.NET Core 5 与 6 托管模型之间的差异。

    使用自定义依赖项注入 (DI) 容器时,请添加以下突出显示的代码:

    using Autofac;
    using Autofac.Extensions.DependencyInjection;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.Extensions.Hosting;
    var builder = WebApplication.CreateBuilder(args);
    var startup = new Startup(builder.Configuration);
    startup.ConfigureServices(builder.Services);
    // Using a custom DI container.
    builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
    builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);
    var app = builder.Build();
    startup.Configure(app, app.Environment);
    app.Run();
    
    using Autofac;
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
            services.AddRazorPages();
        //  Using a custom DI container
        public void ConfigureContainer(ContainerBuilder builder)
            // Configure custom container.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            if (!env.IsDevelopment())
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(endpoints =>
                endpoints.MapRazorPages();
    

    使用最小托管模型时,终结点路由中间件会包装整个中间件管道,因此无需显式调用 UseRouting 或 UseEndpoints 来注册路由。 UseRouting 仍可用于指定进行路由匹配的位置,但如果应在中间件管道开头匹配路由,则无需显式调用 UseRouting。

    在下面的代码中,从 Startup 中删除了对 UseRouting 和 UseEndpoints 的调用。 MapRazorPages 在 中 Program.cs调用 :

    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
            services.AddRazorPages();
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            if (!env.IsDevelopment())
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            //app.UseRouting();
            //app.UseEndpoints(endpoints =>
            //    endpoints.MapRazorPages();
            //});
    
    using Microsoft.AspNetCore.Builder;
    var builder = WebApplication.CreateBuilder(args);
    var startup = new Startup(builder.Configuration);
    startup.ConfigureServices(builder.Services);
    var app = builder.Build();
    startup.Configure(app, app.Environment);
    app.MapRazorPages();
    app.Run();
    

    将 Startup 与新的最小托管模型结合使用时,请记住以下差异:

  • Program.cs 控制 类的 Startup 实例化和生存期。
  • 注入 Configure 方法中的其他任何服务都需要通过 Program 类手动解析。
  • ASP.NET Core 5 与 6 托管模型之间的差异

  • 在开发模式下,开发人员异常页中间件在默认情况下处于启用状态。
  • 应用名称默认为入口点程序集的名称:Assembly.GetEntryAssembly().GetName().FullName。 使用库中的 WebApplicationBuilder 时,会将应用名称显式更改为库的程序集,以便 MVC 的应用程序部件发现可正常工作。 有关详细说明,请参阅本文档中的更改内容根、应用名称和环境。
  • 终结点路由中间件会包装整个中间件管道,因此无需显式调用 UseRouting 或 UseEndpoints 来注册路由。 UseRouting 仍可用于指定进行路由匹配的位置,但如果应在中间件管道开头匹配路由,则无需显式调用 UseRouting。
  • 管道会在任何 IStartupFilter 运行之前创建,因此生成管道时导致的异常对 IStartupFilter 调用链不可见。
  • 某些工具(如 EF 迁移)使用 Program.CreateHostBuilder 访问应用的 IServiceProvider,以在应用上下文中执行自定义逻辑。 这些工具已更新为使用新方法在应用上下文中执行自定义逻辑。 实体框架迁移是采用此方式使用 Program.CreateHostBuilder 的工具示例。 我们正在努力确保更新工具以使用新模型。
  • 创建 WebApplicationBuilder 之后,无法更改任何主机设置,例如应用名称、环境或内容根。 有关更改主机设置的详细说明,请参阅自定义IHostBuilder 或 IWebHostBuilder。 以下突出显示的 API 会引发异常:
  • var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddRazorPages();
    // WebHost
        builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        builder.WebHost.UseEnvironment(Environments.Staging);
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);
    catch (Exception ex)
        Console.WriteLine(ex.Message);
    // Host
        builder.Host.UseEnvironment(Environments.Staging);
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        // TODO: This does not throw
        builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
    catch (Exception ex)
        Console.WriteLine(ex.Message);
    var app = builder.Build();
    if (!app.Environment.IsDevelopment())
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.MapRazorPages();
    app.Run();
    
  • 无法从 WebApplicationBuilder.Host 或 WebApplicationBuilder.WebHost 使用 Startup 类。 以下突出显示的代码会引发异常:

    var builder = WebApplication.CreateBuilder(args);
        builder.Host.ConfigureWebHostDefaults(webHostBuilder =>
            webHostBuilder.UseStartup<Startup>();
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        throw;    
    builder.Services.AddRazorPages();
    var app = builder.Build();
    
    var builder = WebApplication.CreateBuilder(args);
        builder.WebHost.UseStartup<Startup>();
    catch (Exception ex)
        Console.WriteLine(ex.Message);
        throw;    
    builder.Services.AddRazorPages();
    var app = builder.Build();
    
  • WebApplicationBuilder (WebApplicationBuilder.Host) 上的 IHostBuilder 实现不会延迟 ConfigureServices、ConfigureAppConfiguration 或 ConfigureHostConfiguration 方法的执行。 不延迟执行使得使用 WebApplicationBuilder 的代码可以观察到对 IServiceCollection 和 IConfiguration 进行的更改。 下面的示例仅添加 Service1 作为 IService:

    using Microsoft.Extensions.DependencyInjection.Extensions;
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.ConfigureServices(services =>
        services.TryAddSingleton<IService, Service1>();
    builder.Services.TryAddSingleton<IService, Service2>();
    var app = builder.Build();
    // Displays Service1 only.
    Console.WriteLine(app.Services.GetRequiredService<IService>());
    app.Run();
    class Service1 : IService
    class Service2 : IService
    interface IService
    

    在上面的代码中,builder.Host.ConfigureServices 回调进行内联调用,而不是延迟到调用了 builder.Build。 这意味着 Service1 会在 Service2 之前添加到 IServiceCollection,从而导致为 IService 解析 Service1。

    为 ASP.NET Core 6 生成库

    现有 .NET 生态系统围绕 IServiceCollection、IHostBuilder 和 IWebHostBuilder 构建扩展性。 这些属性在 WebApplicationBuilder 上作为 Services、Host 和 WebHost 来提供。

    WebApplication 实现了 Microsoft.AspNetCore.Builder.IApplicationBuilder 和 Microsoft.AspNetCore.Routing.IEndpointRouteBuilder。

    生成 ASP.NET Core 特定组件时,我们期望库创建者继续面向 IHostBuilder、IWebHostBuilder、IApplicationBuilder 和 IEndpointRouteBuilder。 这可确保中间件、路由处理程序或其他扩展点可继续跨不同的托管模型正常工作。

    常见问题解答 (FAQ)

  • 新的最小托管模型是否减少了功能?

    不是。 新的托管模型在功能上等效于 IHostBuilder 和 IWebHostBuilder 支持的 98% 的方案。 有一些高级方案需要对 IHostBuilder 采用特定解决方法,但我们预计这种情况非常罕见。

  • 通用托管模型是否已弃用?

    不是。 通用托管模型是受到无限支持的替代模型。 通用主机支持新的托管模型,仍是托管基于辅助角色的应用程序的主要方式。

  • 是否必须迁移到新的托管模型?

    不是。 新的托管模型是使用 .NET 6 和更高版本托管新应用的首选方法,但不强制更改现有应用中的项目布局。 这意味着应用可以通过将项目文件中的目标框架从 net5.0 更改为 net6.0,从 .NET 5 升级到 .NET 6。 有关详细信息,请参阅本文中的更新目标框架部分。 但是,建议将应用迁移到新的托管模型,以利用仅适用于新的托管模型的新功能。

  • 是否必须使用顶级语句?

    不是。 新项目模板全都使用顶级语句,不过可以在任何 .NET 6 应用中使用新的托管 API 来托管 Web 服务器或 Web 应用。

  • 将存储为字段的状态放置在 Program 或 Startup 类中的哪个位置?

    强烈建议在 ASP.NET Core 应用中使用依赖项注入 (DI) 来流式传输状态。

    有两种方法可用于在 DI 外部存储状态:

  • 将状态存储在其他类中。 存储在类中会采用可以从应用中的任何位置访问的静态状态。

  • 使用由顶级语句生成的 Program 类存储状态。 使用 Program 存储状态是语义方法:

    var builder = WebApplication.CreateBuilder(args);
    ConfigurationValue = builder.Configuration["SomeKey"] ?? "Hello";
    var app = builder.Build();
    app.MapGet("/", () => ConfigurationValue);
    app.Run();
    partial class Program
        public static string? ConfigurationValue { get; private set; }
    

    支持自定义 DI 容器。 有关示例,请参阅自定义依赖项注入 (DI) 容器。

  • WebApplicationFactory 和 TestServer 是否仍可正常工作?

    是。 WebApplicationFactory<TEntryPoint> 是测试新托管模型的方法。 有关示例,请参见使用 WebApplicationFactory 或 TestServer 进行测试。

    Blazor

    按照本文前面所述的指导将应用更新到 6.0 后,请按照 ASP.NET Core 6.0 的新增功能中的链接采用特定功能。

    若要 为 Blazor 应用采用所有新的 6.0 功能,建议执行以下过程:

  • 通过一个 Blazor 项目模板创建新的 6.0 Blazor 项目。 有关详细信息,请参阅用于 ASP.NET Core Blazor 的工具。
  • 将应用的组件和代码移动到 6.0 应用,进行修改以采用新的 6.0 功能。
  • 迁移 SPA 项目

    从 SPA 扩展迁移Angular应用

    请参阅 此 GitHub 问题

    从 SPA 扩展迁移React应用

    请参阅此 GitHub 问题中的从 Spa 扩展迁移React应用程序

    更新 Docker 映像

    对于使用 Docker 的应用,请更新 Dockerfile FROM 语句和脚本。 使用包含 ASP.NET Core 6.0 运行时的基础映像。 请考虑 ASP.NET Core 5.0 和 6.0 之间的以下 docker pull 命令差异:

    - docker pull mcr.microsoft.com/dotnet/aspnet:5.0
    + docker pull mcr.microsoft.com/dotnet/aspnet:6.0
    

    请参阅 GitHub 问题 中断性变更:默认控制台记录器格式设置为 JSON。

    对 ASP.NET Core Razor SDK 的更改

    Razor 编译器现在利用新的源生成器功能从项目中的 Razor 视图和页面生成编译的 C# 文件。 在以前的版本中:

  • 编译依赖于 RazorGenerate 和 RazorCompile 目标来生成生成的代码。 这些目标不再有效。 在 .NET 6 中,对编译器的单个调用支持代码生成和编译。 RazorComponentGenerateDependsOn 仍受支持,可指定生成运行之前所需的依赖项。
  • 生成了单独的 Razor 程序集 (AppName.Views.dll),其中包含应用程序中编译的视图类型。 此行为已弃用,会生成单个程序集 AppName.dll,其中包含应用类型和生成的视图。
  • AppName.Views.dll 中的应用类型是公共的。 在 .NET 6 中,应用类型处于 AppName.dll 中,不过是 internal sealed。 对 AppName.Views.dll 进行类型发现的应用无法对 AppName.dll 进行类型发现。 下面显示了 API 更改:
  • - public class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    + internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    

    进行以下更改:

  • 以下属性不再适用于单步编译模型。
  • RazorTargetAssemblyAttribute
  • RazorTargetName
  • EnableDefaultRazorTargetAssemblyInfoAttributes
  • UseRazorBuildServer
  • GenerateRazorTargetAssemblyInfo
  • GenerateMvcApplicationPartsAssemblyAttributes
  • 有关详细信息,请参阅 Razor 编译器不再生成 Views 程序集。

    项目模板使用 Duende Identity Server

    项目模板现在使用 Duende Identity 服务器。 有关迁移指南,请参阅 IdentityServer4 v4.1 到 Duende IdentityServer v5。

    Duende Identity Server 是具有互惠许可协议的开放源代码产品。 如果计划在生产中使用 Duende Identity Server,则可能需要从 Duende Software 获取商业许可证并支付许可证费用。 有关详细信息,请参阅 Duende Software:许可证。

    若要了解如何对 ASP.NET Core 使用 Microsoft Azure Active DirectoryIdentity,请参阅Identity (dotnet/aspnetcore GitHub 存储库) 。

    将名为 Keys 的 DbSet<Key> 属性添加到每个 IdentityDbContext,以满足 IPersistedGrantDbContext 的更新版本中的新要求。 密钥需要包含在与 Duende Identity Server 存储的协定中。

    public DbSet<Key> Keys { get; set; }
    

    必须为 Duende Identity Server 重新创建现有迁移。

    迁移到 ASP.NET Core 6.0 的代码示例

    迁移到 6.0 中新的最小托管模型的代码示例

    查看中断性变更

    请参阅以下资源:

  • Identity:UI 的默认启动版本已更改
  • 从版本 5.0 到 6.0 的迁移的中断性变更:包括 ASP.NET Core 和 Entity Framework Core。
  • 公告 GitHub 存储库(aspnet/Announcements,6.0.0 标签):包括中断性和非中断性信息。
  • 空引用类型 (NRT) 和 .NET 编译器 Null 状态静态分析

    ASP.NET Core 项目模板使用空引用类型 (NRT),.NET 编译器会执行 Null 状态静态分析。 这些功能随 C# 8 一起发布,默认已为使用 ASP.NET Core 6.0 (C# 10) 或更高版本生成的应用启用。

    .NET 编译器的 Null 状态静态分析警告可充当本地更新文档示例或示例应用的指示,也可忽略。 可以通过在应用的项目文件中将 Nullable 设置为 disable 来禁用 Null 状态静态分析,建议仅将其用于文档示例和示例应用(如果编译器警告在你了解 .NET 时会分散你的注意力)。 不建议在生产项目中禁用 Null 状态检查。

    有关 NRT、MSBuild Nullable 属性和更新应用(包括 #pragma 指南)的详细信息,请参阅 C# 文档中的以下资源:

  • 可为空引用类型
  • 可为 null 的引用类型(C# 引用)
  • 了解用于解析可为空警告的方法
  • 使用可为 Null 的引用类型更新代码库以改进 null 诊断警告
  • null 状态静态分析的属性
  • ASP.NET Core 模块 (ANCM)

    如果在安装 Visual Studio 时 (ANCM) 的 ASP.NET Core 模块不是所选组件,或者如果在系统上安装了早期版本的 ANCM,请下载最新的 .NET Core 托管捆绑包安装程序 (直接下载) 并运行安装程序。 有关详细信息,请参阅 托管捆绑包。

    应用程序名称更改

    在 .NET 6 中, WebApplicationBuilder 规范化以 结尾 DirectorySeparatorChar的内容根路径。 大多数从 HostBuilder 或 WebHostBuilder 迁移的应用不会具有相同的应用名称,因为它们未规范化。 有关详细信息,请参阅 SetApplicationName

  • 迁移到 6.0 中新的最小托管模型的代码示例
  •