從 ASP.NET Core 5.0 移轉至 6.0

本文說明如何將現有的 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

必要條件

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

如果您依賴 global.json 檔案來以特定 .NET SDK 版本為目標,請將 version 屬性更新為已安裝的 .NET 6.0 SDK 版本。 例如:

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

更新目標 Framework

將專案檔的目標 Framework Moniker (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.csProgram.cs 統一成單一 Program.cs 檔案。
  • 使用最上層陳述式,將應用程式所需的程式碼降至最低。
  • 使用全域 using 指示詞,消除所需的 using 陳述式行數或將其降至最低。

下列程式碼會顯示來自 ASP.NET Core 5 Web 應用程式範本 (Razor Pages) 的 Startup.csProgram.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();
            }
            else
            {
                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 範例展示下列作法:

本文件稍後會提供詳細範例,展示如何使用最小裝載模型,將 ASP.NET Core 5 Startup 程式碼移轉至 ASP.NET Core 6。

針對 Web 應用程式範本所產生的其他檔案有一些變更:

- public string RequestId { get; set; }
+ public string? RequestId { get; set; }
  • 記錄層級預設值已在 appsettings.jsonappsettings.Development.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 狀態分析的詳細資訊,請參閱可為 Null 的參考型別 (NRT) 和 .NET 編譯器 Null 狀態靜態分析一節。

移轉至或使用 6.0 和更新版本的應用程式不需要使用新的最小裝載模型

完全支援使用 ASP.NET Core 3.1 和 5.0 範本所使用的 Startup泛型主機

搭配新的最小裝載模型使用 Startup

ASP.NET Core 3.1 和 5.0 應用程式可以搭配新的最小裝載模型使用其 Startup 程式碼。 搭配最小裝載模型使用 Startup 具有下列優點:

  • 不會使用隱藏的反映來呼叫 Startup 類別。
  • 因為開發人員控制對 Startup的呼叫,所以可以撰寫非同步程式碼。
  • 可以撰寫交錯使用 ConfigureServicesConfigure 的程式碼。

搭配新的最小裝載模型使用 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();
        }
        else
        {
            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();
        });
    }
}

使用最小裝載模型時,端點路由中介軟體會包裝整個中介軟體管線,因此不需要明確呼叫 UseRoutingUseEndpoints 來註冊路由。 UseRouting 仍然可以用來指定路由比對發生的位置,但如果中介軟體管線開頭處應該比對路由,則不需要明確呼叫 UseRouting

在下列程式碼中,對 UseRoutingUseEndpoints 的呼叫會從 Startup 中移除。 在 Program.cs 中呼叫 MapRazorPages

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 裝載模型之間的差異

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

// WebHost

try
{
    builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

// Host
try
{
    builder.Host.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    // 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.HostWebApplicationBuilder.WebHost 使用 Startup 類別。 下列醒目提示的程式碼擲回一個例外狀況:

    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        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);
    
    try
    {
        builder.WebHost.UseStartup<Startup>();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
  • WebApplicationBuilder (WebApplicationBuilder.Host) 上的 IHostBuilder 實作不會延遲 ConfigureServicesConfigureAppConfigurationConfigureHostConfiguration 方法的執行。 不延遲執行可讓使用 WebApplicationBuilder 的程式碼觀察對 IServiceCollectionIConfiguration 所做的變更。 下列範例只會將 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,並導致 Service1 針對 IService 進行解析。

建置 ASP.NET Core 6 的程式庫

現有的 .NET 生態系統是圍繞著 IServiceCollectionIHostBuilderIWebHostBuilder 建置擴充性。 這些屬性可在 WebApplicationBuilder 上當作 ServicesHostWebHost 使用。

WebApplication 同時實作 Microsoft.AspNetCore.Builder.IApplicationBuilderMicrosoft.AspNetCore.Routing.IEndpointRouteBuilder

我們預期程式庫作者在建置 ASP.NET Core 特定元件時,會繼續以 IHostBuilderIWebHostBuilderIApplicationBuilderIEndpointRouteBuilder 為目標。 這可確保您的中介軟體、路由處理常式或其他擴充點繼續跨不同裝載模型運作。

常見問題集 (FAQ)

  • 新的最小裝載模型功能是否較差?

    否。 新的裝載模型在功能上相當於 IHostBuilderIWebHostBuilder 所支援案例的 98%。 有一些進階案例需要 IHostBuilder 的特定因應措施,但我們預期這些案例非常罕見。

  • 泛型裝載模型是否已遭取代?

    否。 泛型裝載模型是無限期支援的替代模型。 泛型主機支持新的裝載模型,而且仍然是裝載背景工作角色型應用程式的主要方式。

  • 我是否必須移轉至新的裝載模型?

    否。 新的裝載模型是使用 .NET 6 和更新版本裝載新應用程式的慣用方式,但不會強制您變更現有應用程式中的專案配置。 這表示應用程式可以從 .NET 5 升級至 .NET 6,方法是將專案檔中的目標 Framework 從 net5.0 變更為 net6.0。 如需詳細資訊,請參閱本文中的更新目標 Framework 一節。 不過,我們建議應用程式移轉至新的裝載模型,以利用僅供新裝載模型使用的新功能。

  • 我是否必須使用最上層陳述式?

    否。 新的專案範本全都使用最上層陳述式,但新的裝載 API 可用於任何 .NET 6 應用程式中,來裝載 Web 伺服器或 Web 應用程式。

  • 我在哪裡放置儲存為 ProgramStartup 類別中欄位的狀態?

    我們強烈建議使用相依性插入 (DI),使狀態在 ASP.NET Core 應用程式中流動。

    有兩種方法可在 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) 容器

  • WebApplicationFactoryTestServer 是否仍可運作?

    是。 WebApplicationFactory<TEntryPoint> 是測試新裝載模型的方式。 如需範例,請參閱使用 WebApplicationFactoryTestServer 進行測試

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 的應用程式,請更新 DockerfileFROM 陳述式和指令碼。 使用包含 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# 檔案。 在舊版中:

  • 編譯依賴 RazorGenerateRazorCompile 目標來產生已產生的程式碼。 這些目標不再有效。 在 .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 Server。 如需移轉指引,請參閱 IdentityServer4 v4.1 to Duende IdentityServer v5

重要

Duende Identity Server 是具有互惠授權合約的開放原始碼產品。 如果您打算在實際執行中使用 Duende Identity Server,您可能需要從 Duende Software 取得商業授權,並支付授權費用。 如需詳細資訊,請參閱 Duende Software:授權

若要了解如何將 Microsoft Azure Active Directory 用於 ASP.NET Core Identity,請參閱 Identity (dotnet/aspnetcore GitHub repository)

將名為 KeysDbSet<Key> 屬性新增至每個 IdentityDbContext,以滿足更新版 IPersistedGrantDbContext 的新需求。 在與 Duende Identity Server 商店簽訂合約的過程中需要金鑰。

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

注意

必須針對 Duende Identity Server 重新建立現有的移轉。

移轉至 ASP.NET Core 6.0 的程式碼範例

移轉至 6.0 中新的最小裝載模型的程式碼範例

檢閱中斷性變更

請參閱下列資源:

可為 Null 的參考型別 (NRT) 和 .NET 編譯器 Null 狀態靜態分析

ASP.NET Core 專案範本會使用可為 Null 的參考型別 (NRT),而 .NET 編譯器會執行 Null 狀態靜態分析。 這些功能已隨 C# 8 一起發行,而且預設會針對使用 ASP.NET Core 6.0 (C# 10) 或更新版本所產生的應用程式啟用。

.NET 編譯器的 Null 狀態靜態分析警告可作為在本機更新文件範例或範例應用程式的指南,或將其忽略。 您可以在應用程式的專案檔中將 Nullable 設為 disable,來停用 Null 狀態靜態分析,但只有在編譯器警告在您了解 .NET 時使您分心時,才建議對文件範例和範例應用程式這樣做。 不建議在實際執行專案中停用 Null 狀態檢查。

如需 NRT、MSBuild Nullable 屬性和更新應用程式的詳細資訊 (包括 #pragma 指引),請參閱 C# 文件中的下列資源:

ASP.NET Core 模組 (ANCM)

如果在安裝 Visual Studio 時,ASP.NET Core 模組 (ANCM) 不是選取的元件,或者如果系統上已安裝舊版的 ANCM,請下載最新的 .NET Core 裝載套件組合安裝程式 (直接下載),並執行安裝程式。 如需詳細資訊,請參閱裝載組合套件

應用程式名稱變更

在 .NET 6 中,WebApplicationBuilder 會將內容根路徑正規化,使其以 DirectorySeparatorChar 結尾。 大部分從 HostBuilderWebHostBuilder 移轉的應用程式都不會有相同的應用程式名稱,因為這些應用程式並未正規化。 如需詳細資訊,請參閱 SetApplicationName

其他資源